34

I work mainly with javascript, Jquery, knockout, etc

The thing that attracted eval() to me is

var a = 5;
var b = 10;
eval("a+b");
//Gives me output 15

Note: I work in cases where the value of a and b changes dynamically

In my work I'm dealing with a lot of dynamic objects from json, knockout, etc. So eval solves most of my problems. But as I read I found there are so many issues with eval() like slowing down etc.

I searched a lot and haven't found any substitute for eval() when i have to evaluate equation obtaining as string into equation as object.

Can anyone suggest a plugin or function alternative to eval() keeping in mind the example i have given above

Problem:

I'm creating a Table from Json data using knockout mapping. So that what ever the format of json is the table is generated. I also calculate some field using knockout computed. Right now I use hard-coded

self.Salary = ko.computed(function(){ return self.salaryEqn() && eval(self.salaryEqn()).toFixed(2); })
self.salaryEqn(salEqnTxt); 

I want to execute these equations dynamic. I can create it dynamicaly as string but to eval them is the issue I'm facing.

I want solution for

Is there a way to calculate a formula stored in a string in JavaScript without using eval?

Like a formula

 "self.Salary = ko.computed(function(){ return self.salaryEqn() && eval(self.salaryEqn()).toFixed(2); })"
Okky
  • 10,338
  • 15
  • 75
  • 122
  • It won't work for your example, but if what you need is `to evaluate equation obtaining as string into equation as object.` then you could use `JSON.parse` – Claudio Redi Apr 16 '13 at 12:27
  • 2
    `a + b` gives you `15` without having to represent it as a string and then evaling it. – Quentin Apr 16 '13 at 12:32
  • @ClaudioRedi will that also give the same result as eval("a+b") – Okky Apr 16 '13 at 12:33
  • @Quentin I work with cases where the values of a and b changes dynamicaly – Okky Apr 16 '13 at 12:34
  • @Okky — The trouble is that you've simplified your problem so much we can't tell what it is. Your question is "How can I solve X, which can be solved by eval, without using eval?". We don't have enough information to understand what X is. – Quentin Apr 16 '13 at 12:36
  • Can you specify the problems you're facing exactly? You can always use or create a formula parser, but you would face the same performance issues than when using eval(). – Lâm Tran Duy Apr 16 '13 at 12:36
  • @Okky you might want to specify, which kinds of expressions do you wish to evaluate. – pfyod Apr 16 '13 at 12:37
  • 2
    In general you should avoid using eval() whenever possible. Check the below link for the problem you face while using eval(). http://ajaxmin.codeplex.com/wikipage?title=Problems%20with%20Evals **UPDATE:** Check this [stackoverflow](http://stackoverflow.com/questions/2029888/what-are-the-alternatives-to-eval-in-javascript?rq=1) answer for alternative of eval in javascript. – RGR Apr 16 '13 at 12:29

6 Answers6

28

Javascript is a very flexible language in this regard. There are very very few cases where eval() is the right answer to any given question, and it certainly isn't necessary here.

If your a and b variables are part of an object, you can access them with string subscripts:

ie myobj.a could also be referenced as myobj['a'].

From that, you can use a variable for the subscript, and thus you can reference any element in myobj dynamically -- ie:

var myobj = {a : 5, b : 10};

var dynamicProperty1 = 'a';
var dynamicProperty2 = 'b';

//gives 15.
alert( myobj[dynamicProperty1] + myobj[dynamicProperty2] );

No eval() required. You can build the dynamicProperty strings however you wish, so there's virtually infinite flexibility.

If your a and b variables are globals, JS globals in the browser are actually children of the window object, so you can still use this technique even with globals.

ie your global variable a could also be accessed via window.a or window['a'], with the latter option allowing you to do the same dynamicProperty trick described above.

Hope that helps.

SidTheBeard
  • 379
  • 3
  • 11
Spudley
  • 166,037
  • 39
  • 233
  • 307
5

do you mean that you want to calculate an equation that you can't know until you've received it?

if so see Calculate string value in javascript, not using eval .

in short:

eval CAN be used sometimes, but only if the equation string comes from a trusted source, and there you need something like evaluating dynamic equations.

Community
  • 1
  • 1
user2264587
  • 484
  • 2
  • 6
2

maybe using window['var' + num] might be more useful for you. i don't quite understand your question sorry.

Tyler
  • 152
  • 6
  • 3
    PLEASE do not the window to store variables. PLEASE. Instead use `obj = Object.create(null); obj.a = "value1"; obj.b = " then two"; altert(obj.a + obj.b); // will alert "value1 then two"`; – Jack G Sep 22 '17 at 21:10
  • 1
    except that `obj = ...` is exactly the same than `var obj = ...` or `window['obj'] = ...` – samb102 Aug 12 '20 at 08:42
1

If you can collect them under an object like root = {a: 1, b: 2}, then

Object.observe(root, function(newValues) { 
    res = newValues.object.a + newValues.object.b;
});

can keep your res variable up to date whenever the a or b changes

gre_gor
  • 6,669
  • 9
  • 47
  • 52
erdysson
  • 1,450
  • 13
  • 17
0

It looks like you are trying to do dynamic equations created by a user.

For example it could be 'a+b+c' or 'dog+cat', and you don't know.

The best way to handle user-input equations like that is to parse the text into tokens and then translate the tokens into values/operands.

That's a lot of work, but there are pre-rolled solutions. For example, math.js

matchdav
  • 715
  • 1
  • 7
  • 16
0

Check more alternatives to eval in this question and another one here which both might be considered a duplicate...

I understand this is a link only answer, but it will for sure be helpful to others searching for alteratives to eval.

Community
  • 1
  • 1
Wilt
  • 41,477
  • 12
  • 152
  • 203