Я реализовал минимальный «калькулятор», который будет выполнять манипуляции со стеком, как вы описали.
https://jsbin.com/maberic/5/edit?html,js,output
window.onload = function() {
var stack = [];
var inputField = document.querySelector('#textfield');
var buttons = [];
var buttonsContainer = document.querySelector('#buttons');
var actions = {
'add': '+',
'sub': '-',
'mul': '*',
'div': '/' // you can use custom symbols e.g. "÷" U+00F7 Division Sign Unicode Character
};
var buttonsHandler = function(event) {
var button = event.target;
var action = button.getAttribute('action');
switch (action) {
case 'input':
var value = button.getAttribute('value');
if (stack.length <= 0 || isNaN(parseInt(stack[stack.length - 1], 10))) {
// if empty stack or last is sign we can just push
stack.push(value)
} else {
// else we need to concat last *number*
stack[stack.length - 1] += '' + value; // make sure we have a string
}
inputField.value += value;
break;
case 'action':
var op = button.getAttribute('op');
switch (op) {
case 'bs':
// implement here backspace logic
// e.g. remove last char from number or remove operator entirely
break;
case 'eq':
// implement here logic for "=" button
// avoid using eval: https://medium.com/mail-online/eval-is-evil-but-not-why-you-may-think-25961f9b01bb
break;
case 'cl':
stack = [];
inputField.value = '';
break;
default:
stack.push(actions[op]);
inputField.value += actions[op];
break;
}
break;
default:
break;
}
// here you can apply "post" actions for your stack
};
/* Buttons "generator" */
[ {type: 'input', value: 1 },
{type: 'input', value: 2 },
{type: 'input', value: 3 },
{type: 'linebreak' },
{type: 'input', value: 4 },
{type: 'input', value: 5 },
{type: 'input', value: 6 },
{type: 'linebreak' },
{type: 'input', value: 7 },
{type: 'input', value: 8 },
{type: 'input', value: 9 },
{type: 'linebreak' },
{type: 'dummy' },
{type: 'input', value: 0 },
{type: 'dummy' },
{type: 'linebreak' },
{type: 'action', sign: actions.add, action: 'add'},
{type: 'action', sign: actions.sub, action: 'sub'},
{type: 'linebreak' },
{type: 'action', sign: actions.mul, action: 'mul'},
{type: 'action', sign: actions.div, action: 'div'},
{type: 'linebreak' },
{type: 'action', sign: '=', action: 'eq'},
{type: 'linebreak' },
{type: 'action', sign: '< Backspace', action: 'bs'},
{type: 'action', sign: 'Clear', action: 'cl'} ]
.forEach(function(elem) {
switch(elem.type) {
case 'input':
var button = document.createElement('button');
button.innerText = elem.value.toString();
button.setAttribute('action', 'input');
button.setAttribute('value', elem.value);
button.onclick = buttonsHandler;
buttonsContainer.append(button);
buttons.push(button);
break;
case 'dummy':
var dummy = document.createElement('button');
dummy.innerText = '_';
buttonsContainer.append(dummy);
break;
case 'action':
var action = document.createElement('button');
action.innerText = elem.sign.toString();
action.setAttribute('action', 'action');
action.setAttribute('op', elem.action);
action.onclick = buttonsHandler;
buttonsContainer.append(action);
buttons.push(button);
break;
case 'linebreak':
var br = document.createElement('br');
buttonsContainer.append(br);
break;
default:
break;
}
});
/* end */
}
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Simple calc template">
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width"/>
<title>Example</title>
</head>
<body>
<input id="textfield" type="text" readonly="readonly"/>
<br/>
<div id="buttons"></div>
</body>
</html>
Кроме того, я бы рекомендовал вам не использовать eval: https://medium.com/@epoberezkin/eval-is-evil-but-not-why-you-may-think-25961f9b01bb
Вы можете работать со своим стеком.Но нужно помнить о умножении, делении и т. Д. О порядке действий.