Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
581 views
in Technique[技术] by (71.8m points)

javascript - Eval alternative

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));
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...