Eval alternative

。_饼干妹妹 提交于 2019-12-18 07:16:10

问题


This code works as a calculator, but the scratch pad at codeacademy tells me that eval is evil. Is there another way to do the same thing without using eval?

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

回答1:


eval evaluates the string input as JavaScript and coincidentally JavaScript supports calculations and understands 1+1, which makes it suitable as a calculator.

If you don't want to use eval, which is good, you have to parse that string yourself and, finally, do the computation yourself (not exactly yourself though). Have a look at this math processor, which does what you want.

Basically what you do is:

  1. Read the input string char by char (with this kind of problem it's still possible)
  2. Building a tree of actions you want to do
  3. At the end of the string, you evaluate the tree and do some calculations

For example you have "1+2/3", this could evaluate to the following data structure:

     "+"
     /  \
   "1"  "/"
       /   \
     "2"   "3"

You could then traverse that structure from top to bottom and do the computations. At first you've got the "+", which has a 1 on the left side and some expression on the right side, so you have to evaluate that expression first. So you go to the "/" node, which has two numeric children. Knowing that, you can now compute 2/3 and replace the whole "/" node with the result of that. Now you can go up again and compute the result of the "+" node: 1 + 0.66. Now you replace that node with the result and all you've got left is the result of the expression.

Some pseudo code on how this might look in your code:

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))

As you might have noticed, the tree is designed in such a way that it honors operator precedence. The / has a lower level than the +, which means it get's evaluated first.

However you do this in detail, that's basically the way to go.




回答2:


You can use eval safely for a simple arithmetic calculator by filtering the input- if you only accept digits, decimal points and operators (+,-,*,/) you won't get in much trouble. If you want advanced Math functions, you are better off with the parser suggestions.

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()



回答3:


You can use the expression parser that is included in the math.js library:

http://mathjs.org

Example usage:

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



回答4:


I write some functions when I had a problem like this. Maybe this can help:

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


来源:https://stackoverflow.com/questions/14916902/eval-alternative

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!