此代码用作计算器,但codeacademy的便笺簿告诉我,eval是邪恶的。有没有另外一种方法可以在不使用eval的情况下做同样的事情?
var calculate = prompt("Enter problem");
alert(eval(calculate));
答案 0 :(得分:5)
eval
将字符串输入评估为JavaScript,巧合的是JavaScript支持计算并理解1+1
,这使其适合作为计算器。
如果您不想使用eval
,这是好的,您必须自己解析该字符串,最后自己进行计算(尽管不是自己)。看看this math processor,它可以做你想要的。
基本上你做的是:
例如,您有"1+2/3"
,这可以评估为以下数据结构:
"+"
/ \
"1" "/"
/ \
"2" "3"
然后,您可以从上到下遍历该结构并进行计算。
起初你有"+"
,左边有一个,右边有一些表情,
所以你必须先评估那个表达式。所以你去了"/"
节点,它有两个数字子节点。知道了,您现在可以计算2/3
并用结果替换整个"/"
节点。现在,您可以再次上升并计算“+
”节点的结果:1 + 0.66
。现在用结果替换那个节点,你剩下的就是表达式的结果。
关于代码可能会如何看待的一些伪代码:
calculation(operator, leftValue, rightValue):
switch operator {
case '+': return leftValue + rightValue
case '-': return 42
}
action(node):
node.value = calculation(node.operator, action(node.left) action(node.right))
您可能已经注意到,树的设计方式使其符合运算符优先级。 /
的级别低于+
,这意味着它首先得到评估。
然而,你详细说明了这一点,基本上就是这样。
答案 1 :(得分:1)
您可以通过过滤输入安全地使用eval作为简单的算术计算器 - 如果您只接受数字,小数点和运算符(+, - ,*,/),您将不会遇到太多麻烦。如果您需要高级数学函数,最好使用解析器建议。
function calculate(){
"use strict";
var s= prompt('Enter problem');
if(/[^0-9()*+\/ .-]+/.test(s)) throw Error('bad input...');
try{
var ans= eval(s);
}
catch(er){
alert(er.message);
}
alert(ans);
}
calculate()
答案 2 :(得分:1)
您可以使用math.js库中包含的表达式解析器:
使用示例:
math.eval('1.2 / (2.3 + 0.7)'); // 0.4
math.eval('5.08 cm in inch'); // 2 inch
math.eval('sin(45 deg) ^ 2'); // 0.5
math.eval('9 / 3 + 2i'); // 3 + 2i
math.eval('det([-1, 2; 3, 1])'); // -7
答案 3 :(得分:0)
当我遇到这样的问题时,我写了一些函数。也许这可以提供帮助:
data = [
{id:1,val1:"test",val2:"test2",val2:"test3"},
{id:2,val1:"test",val2:"test2",val2:"test3"},
{id:3,val1:"test",val2:"test2",val2:"test3"}
];
datakey = Object.keys(data[0]);
// here's a fix for e['datakey[f]'] >> e[x]
vix = function(e,f){
a = "string";
e[a] = datakey[f];
x = e.string;
end = e[x];
delete e.string;
return end;
};
// here's a fix to define that variable
vox = function(e,f,string){
a = "string";
e[a] = datakey[f];
x = e.string;
end = e[x] = string;
delete e.string;
};
row = 2 // 3th row ==> {id:3,val1:"test",val2:"test2",val2:"test3"}
column = 1 //datakey 2 ==> val1
vox(data[row],column,"new value");
alert(data[2].val1); //the value that we have changed