I have a string expression like this 10/3*4-7
and I want to know if there is some type of javascript method that can convert the string into an actual expression so that I can get the answer . I have a function that randomly generates numbers and operators, and I want to get the result from the equation. However, the function that I created to get the result only does the calculation from left to right. It does not go by a operator priority, where * and / get calculated first and stuff like that. Is there something in javascript that can do that or would I have to create a function to do something like that?
Asked
Active
Viewed 414 times
-1

black_yurizan
- 407
- 2
- 7
- 19
-
Yes, you could literally use `10/3*4-7` – Tibrogargan Nov 04 '16 at 03:42
-
Please have a look below at my answer – Aruna Nov 04 '16 at 03:45
3 Answers
3
I'd recommend using a library such as Math.js as this will parse the math expression using a regular expression. This will avoid opening the application up to Cross-site scripting (XSS) attacks.
var answer = math.eval('10/3*4-7');
console.log(answer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.6.0/math.min.js"></script>

Graham Walters
- 2,054
- 2
- 19
- 30
-
-
minor thing here: Under the covers math.js uses `Function()`. The big thing you get from using it is that your expression would be parsed first and should be correct. – Tibrogargan Nov 04 '16 at 05:09
-
@Tibrogargan - I can't find it in the source code. Care to post a reference? – I wrestled a bear once. Nov 04 '16 at 13:02
-
@Iwrestledabearonce. in `Node.prototype.compile`. Line 31328 in the most recent dev version, or search for "new Function(" - it's actually used twice. – Tibrogargan Nov 04 '16 at 17:17
-
I was looking at the [source code here](https://github.com/josdejong/mathjs) and I couldn't find that file. It doesn't really matter though, I was just curious to see how it was used. – I wrestled a bear once. Nov 04 '16 at 17:20
-
I was referring to the [live JS](http://cdnjs.cloudflare.com/ajax/libs/mathjs/3.6.0/math.js), not the source. – Tibrogargan Nov 04 '16 at 18:06
0
This function takes either a string expression, or an array of characters that create an expression.
function calculate(expression) {
"strict mode";
if(Array.isArray(expression))
expression = expression.join("");
var allowedChars = "1234567890%^*()-+/. ";
for (var i = 0; i < expression.length; i++)
if (allowedChars.indexOf(expression.charAt(i)) < 0)
throw new Error("Invalid expression: unexpected '" + expression.charAt(i) + "' in '"+expression+"'");
return eval(expression);
}
try{
alert(calculate("4+4"));
alert(calculate([7,"+",9,"/",34]));
alert(calculate("45/3"));
alert(calculate("100 * cheeseburger"));
}catch(e){
alert(e.message);
}
Here's why this is safe:
- Improper use of eval opens up your code for injection attacks
- In
strict mode
eval
is not able to introduce new variables to the surrounding scope. (As it's at the end of it's own function, nothing else is happening in that scope anyway.) - The function will throw an error if any character is present which is not part of a mathematical expression, making injection impossible.
- In
- With
eval
, debugging can be more challenging (no line numbers, etc.)- In this case the function throws an Error, which includes a line number. The
eval
'd code is only so a single line, so this is not relevant.
- In this case the function throws an Error, which includes a line number. The
eval
'd code executes more slowly (no opportunity to compile/cache eval'd code)- In this case there is nothing to compile/cache, so this is not an issue.

I wrestled a bear once.
- 22,983
- 19
- 69
- 116
-1
There is quite a discussion here on why you should not use eval()
unless there are no clear alternatives. Using eval()
in this case is completely unnecessary as shown in the example below:
var expression = "10/3*4-7";
var foo = Function('"use strict"; return '+expression);
console.log(foo());

Community
- 1
- 1

Tibrogargan
- 4,508
- 3
- 19
- 38
-
I don't know about "all broswers", but this mechanism has been in JavaScript for at least 19 years (since ECMA 1.0). I'd be surprised if there were any mainstream browsers that didn't support it – Tibrogargan Nov 04 '16 at 04:00
-
Function is JS standard and is supported in all browers. However it is insecure for literally the exact same reason as eval. There is no benefit to this over eval whatsoever. – I wrestled a bear once. Nov 04 '16 at 04:02
-
@Iwrestledabearonce using eval() will disable compiler optimization. – Tibrogargan Nov 04 '16 at 04:03
-
Compiler optimization? what are talking about? references, please. – I wrestled a bear once. Nov 04 '16 at 04:05
-
Oh I get it. You're parroting the selected answer in the question you linked to. I guess you thought `Function` would use magic instead of the interpreter to evaluate the string.. – I wrestled a bear once. Nov 04 '16 at 04:11
-
@Iwrestledabearonce. Actually, it's was from a discussion on another question that I've been trying to track down. I think I'll skip it, since you have all the answers – Tibrogargan Nov 04 '16 at 04:20
-
-
As it turns out, not quite. But effectively yes. Found the reference I was looking for [here](https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#eval). `eval()` (along with `Function()`, :/) cause the JS Engine to not do optimization of any code because it can't trust the results. `Function()` is marginally better because it's not lexically scoped. – Tibrogargan Nov 04 '16 at 04:38
-
@Iwrestledabearonce. `eval()` has access to the local scope and can modify local variables. `Function()` cannot, it's globally scoped not lexically scoped. – Tibrogargan Nov 04 '16 at 04:50
-
ok, i guess that's a point, though i'm not sure how relevant it is when one could simply put it in a closure and give it it's own scope.] – I wrestled a bear once. Nov 04 '16 at 04:59
-
Looks like math.js uses `Function()`, At least you should be guaranteed of reasonably clean expression. – Tibrogargan Nov 04 '16 at 05:04
-
@Iwrestledabearonce. It comes down to: Does putting `eval()` anywhere in your JS turn off the JS Engine optimizations for *everything*, or just the local scope? If it's just the local scope then sure - put it in a closure and you're good. If it's the entire file then use `Function()` – Tibrogargan Nov 04 '16 at 05:06
-
@Tibrogargan - I appreciate your argument because I'm learning things, however you should take a closer look at the article you linked to a few lines up. These "optimizations" are about bookmarking points in the code where there are variables, etc, for easy reference. They are not "compiler" optimizations as JS is script and is not compiled. Both Function and eval disable these "optimizations." And finally, none of these "optimizations" apply to the use-case at hand. No variables are being created, so there is no optimizations to be done anyway. – I wrestled a bear once. Nov 04 '16 at 12:56