eval() with variables from an object in th

2019-05-22 12:35发布

问题:

how can I execute a string as code (using eval()) and give it some variables? For example, I've got an object named vars and want each of its properties to be accessible for the code without exciplitely specifying the objects name. Something like this:

function evalWithVariables(func, vars) {
 //some magic here
 return eval(func);
}

function test() {
 var retval = evalWithVariables("a>5", {"a":7});
 console.log(retval);
}

Oh, and the code is trusted, it comes from the same server as the script, it is not user-generated and I'm pretty sure that eval is the right tool here (and I know that eval is often evil).

Edit: The most important thing for me is that the code that gets passed to eval() looks good, is short and doesn't have to contain helper variable names or so.

回答1:

Discovered that it's possible to just use with:

eval("with (vars) {var result = (" + func + ")}");


回答2:

You can reconstitute the values as JavaScript code and prepend it the code to be executed. Then, assign the result of the actual expression to a local variable. So,

evalWithVariables("a>5", {"a":7});

actually evals:

var a=7; var result = (a>5);

Then, right after the eval, check the value of result:

function evalWithVariables(func, vars) {
 var varString = "";

 for (var i in vars)
     varString += "var " + i + " = " + vars[i] + ";";   

 eval(varString + "; var result = (" + func + ")");
 return result;
}


回答3:

An option to forgo eval() is to generate a function and then use with(), as you did, to change the block scope:

function evalWithVariables(func, vars) {
    return new Function("v", "with (v) { return (" + func +")}")(vars);
}


回答4:

Maybe you use a more functional approach:

function evalWithVariables(func, vars) {
    return func(vars);
}
evalWithVariables(function(vars) { return vars.a > 5; }, {"a":7})

Or shorter:

(function(vars) { return vars.a > 5; })({"a":7})