Eval alternative

匿名 (未验证) 提交于 2019-12-03 02:29:01

问题:

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


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