Eval替代品

时间:2013-02-17 00:52:37

标签: javascript math eval calculator

此代码用作计算器,但codeacademy的便笺簿告诉我,eval是邪恶的。有没有另外一种方法可以在不使用eval的情况下做同样的事情?

var calculate = prompt("Enter problem");
alert(eval(calculate));

4 个答案:

答案 0 :(得分:5)

eval将字符串输入评估为JavaScript,巧合的是JavaScript支持计算并理解1+1,这使其适合作为计算器。

如果您不想使用eval,这是好的,您必须自己解析该字符串,最后自己进行计算(尽管不是自己)。看看this math processor,它可以做你想要的。

基本上你做的是:

  1. 通过char读取输入字符串char(这种问题仍然存在)
  2. 构建您想要执行的操作树
  3. 在字符串的末尾,您评估树并进行一些计算
  4. 例如,您有"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库中包含的表达式解析器:

http://mathjs.org

使用示例:

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