Let’s assume we want to implement a function
evalExpr(expr, vars)That function evaluates expr, the object in vars provides the values for variables. Example:
> evalExpr("x + y", { x: 5, y: 3 })
8
The classic approach is:
function evalExpr(expr, vars) {
with (vars) {
return eval(expr);
}
}
But that approach uses the controversial with statement. A different approach comprises the following steps:
function evalExpr(expr, vars) {
var keys = Object.keys(vars);
// Function(param1, ..., paramn, body)
var exprFunc = Function.apply(null, keys.concat(["return "+expr]));
var args = keys.map(function (key) { return vars[key] });
return exprFunc.apply(null, args);
}
The above code uses ECMAScript 5 functionality (Object.keys(), Array.prototype.map()), but you can add that functionality to older browsers via a shim [3].
Note that the usual security concerns about eval apply here, too: You have to make sure that all ingredients come from trusted sources. But there are legitimate uses for this technique, e.g. for templating.
References: