问题
I am making a calculator and pushing/saving all the numbers and operators clicked to an array and a string.
I want to know which approach is the best in this case. Making a string or an array from the input OR a better approach I can't think of.
I want to compute the array or string. The string is giving wrong answers and I don't have a clue on how I can compute the array. The demo calculator is below.
$(document).ready(function(){
var inputArr = [];
var inputStr = '';
$('span').click(function(){
$('#input').append($(this).text());
//push to inputArr
inputArr.push($(this).text());
//add to inputStr
inputStr += $(this).text();
});
//Get result
$('.equals').click(function(){
$('#result').text(inputArr);
$('#result').append("<br/>" + parseInt(inputStr));
});
$('.clear').click(function(){
// clear everything
$('#input').text('');
inputArr = [];
inputStr = '';
});
});
span {
background: #bbb;
border-radius: 2px;
margin: 5px;
padding: .5em;
cursor: pointer;
}
.equals{
width: 30%;
background: #bbb;
border-radius: 2px;
margin: 15px;
padding: .5em;
cursor: pointer;
text-align: center;
font-size: 1.5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span>
<br/>
<br/>
<span>6</span> <span>7</span> <span>8</span> <span>9</span> <span>0</span>
<br/><br/>
<span>+</span><span>-</span><span>*</span><span>/</span><span class='clear'>clear</span>
<p class="equals"> = </p>
<p id="input"></p>
<p id='result'></p>
I tried using parseInt(inputStr)
but it gives wrong answers.
回答1:
This function takes either a string expression, or an array of characters that create an expression.
function calculate(expression) {
"strict mode";
if (Array.isArray(expression))
expression = expression.join("");
var allowedChars = "1234567890%^*()-+/. ";
for (var i = 0; i < expression.length; i++)
if (allowedChars.indexOf(expression.charAt(i)) < 0)
throw new Error("Invalid expression: unexpected '" + expression.charAt(i) + "' in '" + expression + "'");
return eval(expression);
}
try {
alert(calculate("4+4"));
alert(calculate([7, "+", 9, "/", 34]));
alert(calculate("45/3"));
alert(calculate("100 * cheeseburger"));
} catch (e) {
alert(e.message);
}
Here's why this is safe:
- Improper use of eval opens up your code for injection attacks
- In strict mode
eval
is not able to introduce new variables to the surrounding scope. (As it's at the end of it's own function, nothing else is happening in that scope anyway.) - The function will throw an error if any character is present which is not part of a mathematical expression, making injection impossible.
- In strict mode
- With
eval
, debugging can be more challenging (no line numbers, etc.)- In this case the function throws an Error, which includes a line number. The
eval
'd code is only so a single line, so this is not relevant.
- In this case the function throws an Error, which includes a line number. The
eval
'd code executes more slowly (no opportunity to compile/cache eval'd code)- In this case there is nothing to compile/cache, so this is not an issue.
回答2:
parseInt
doesn't evaluate a string with mathematical operations. eval
will do this. If you are worried about the safety of using eval
, you will have to write a calculator function that parses a string and observes order of operations (a much more involved task). I see no reason to keep both an array AND a string. Either will suffice.
Working code snippet with minimal modifications:
$(document).ready(function(){
var inputStr = '';
$('span').click(function(){
$('#input').append($(this).text());
//add to inputStr
inputStr += $(this).text();
});
//Get result
$('.equals').click(function(){
// or however you want to format it
$('#result').text(inputStr + ' = ' + eval(inputStr));
});
$('.clear').click(function(){
// clear everything
$('#input').text('');
$('#result').text('');
inputArr = [];
inputStr = '';
});
});
span {
background: #bbb;
border-radius: 2px;
margin: 5px;
padding: .5em;
cursor: pointer;
}
.equals{
width: 30%;
background: #bbb;
border-radius: 2px;
margin: 15px;
padding: .5em;
cursor: pointer;
text-align: center;
font-size: 1.5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span>
<br/>
<br/>
<span>6</span> <span>7</span> <span>8</span> <span>9</span> <span>0</span>
<br/><br/>
<span>+</span><span>-</span><span>*</span><span>/</span><span class='clear'>clear</span>
<p class="equals"> = </p>
<p id="input"></p>
<p id='result'></p>
来源:https://stackoverflow.com/questions/40433498/how-do-i-compute-an-array-or-string-of-numbers-and-mathematical-operators