Black lives matter

(Ad, please don’t block)

Problem: You have an object that assigns values to names and want to use those names in an expression that is to be evaluated by `eval`. The classic solution is to use the `with` statement. But that statement is deprecated [1], starting with ECMAScript 5 strict mode [2]. This blog post describes an alternative implementation technique.

Let’s assume we want to implement a function

evalExpr(expr, vars)That function evaluates

> evalExpr("x + y", { x: 5, y: 3 }) 8The classic approach is:

function evalExpr(expr, vars) { with (vars) { return eval(expr); } }But that approach uses the controversial

- Wrap a function expression (not a function declaration!) around
`expr`whose parameters are the variables listed in`vars`. - Evaluate the function expression.
- Call the resulting function with the property values of
`vars`, in the same order as the parameters.

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 (

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:**