0

I'm trying to use eval() to evalute a mathematical string with variables and functions

ex: algo = "1+len+customfunction(6)"

So i have data for len and the function for customFunction.

They are obviously declared in different scope.

I tried with something like

process = function(vars, algo) {
 return (function() {
    algo = algo.toLowerCase();
    return eval(algo);
  }).call(vars);
};

I need to provide required functions and variables to eval. Items are in different scopes, how do i do that ?

Now I'm a bit lost and confused, is this even possible ? I think using eval('var'+vName+'='+value) would be ok for vars but not suitable for functions.

EDIT: btw eval can be replaced with (new Function(algo))() http://moduscreate.com/javascript-performance-tips-tricks/

Kwaadpepper
  • 516
  • 4
  • 15
  • 1
    JavaScript is case-sensitive. You probably don't want to convert the code to be executed using `eval` to lower case. – Anthony Grist Apr 23 '15 at 14:56
  • yes but my input is non case sensitive. I want this behavior – Kwaadpepper Apr 23 '15 at 14:57
  • Ok my bad, i'll correct the example – Kwaadpepper Apr 23 '15 at 15:00
  • I need to provide required functions and variables to eval. Items are in different scopes. – Kwaadpepper Apr 23 '15 at 15:04
  • Check out [this function](http://stackoverflow.com/a/24032179/1048572) which lets you inject some selected values in a "eval"-scope – Bergi Apr 23 '15 at 15:37
  • Where does your `customFunction` come from? Where is it stored, how can it be accessed (without the eval yet, I mean)? – Bergi Apr 23 '15 at 15:39
  • eval has always window as context, didn't manage to change this, my functions are nested in window.class.functions like path. You function seems awesome however it will be very complicated to maintain the function's body in a string. I'm thinking of replacing my function with fullpath at runtime and create vars with a loop on eval. Dont know wich solution is more simple :s – Kwaadpepper Apr 23 '15 at 16:00

2 Answers2

0

i would move the required data to an object, which hold all required items. access is possible with any given string. this solution does not requires eval()

var data = {
    customfunction: function (x) {
        return Math.PI * x * x;
    },
    len: 5
};
var variable = 'len';
if (data[variable]) {
    // do something
    ;
}
var fn = 'customFunction';
function evaluate(vars, algo) {
    if (data[algo.toLowerCase()]) { // 
        return data[algo.toLowerCase()].call(vars);
    } else {
        // fallback
    }
}
var process = evaluate(vars, algo);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Sorry, i just understood the why my question wasn't clear enough, algo contains user mathematical formula, it can be evaluated with app functions and vars – Kwaadpepper Apr 23 '15 at 15:21
  • please provide an example for `len` and `customfunction`. – Nina Scholz Apr 23 '15 at 15:54
  • len = 5; customfunction = function(a,b) { return a+b }; eval('2+4+len+customfunction(6+6)'); should print 18, but eval isn't aware of len and custom function as its context is window – Kwaadpepper Apr 23 '15 at 16:08
0

OK here is what i've found :

  • we can't provide a context for eval
  • eval('1+1') can be replaced by ((new Function('1+1'))() and it's way faster
  • eval have different scopes, can't use eval('var a = 1'); eval('alert(a)');

So, i'v managed to :

  • create a string to initiate all vars : vars += 'var '+key+'='+JSON.stringify(value)+';'
  • replace at runtime my algo string functions with their full path :

    var algo = 'f(x)+5*2', x = 5;

    window.object.functions.x = function(a) { return a*2; };

    So at runtime i replace x( with object.functions.x( the code executed by eval finally is eval('object.functions.x(5)+5*2'); and output is 20 of course :)

It seems to work.

Kwaadpepper
  • 516
  • 4
  • 15