A fun little spec deviation in the major JS engines

felix felix8a at gmail.com
Sat Jan 28 20:20:26 PST 2012

On Sat, Jan 28, 2012 at 7:13 PM, Jeff Walden <jwalden+es at mit.edu> wrote:
> At least, if you consider |with| and |eval| fun (and who doesn't?):
>  js> var x = "outer"; function f() { with({ x: 17 }) eval("var x"); return
> x; } typeof f()
>  "undefined"
> This seems to be the behavior in every engine out there.  But according to
> the last ES5 errata for 10.5, and in the latest ES6 draft, since "x" has a
> binding in the object environment record created when executing the |with|
> statement's substatement, and the object supplied to the |with| isn't the
> global object, the |var x| should do nothing whatsoever.  Presumably given
> this implementation unanimity the spec should change on this point.

It seems to me the behavior you observe conforms to spec.

12.10, the with statement changes the Lexical Environment, but not the
Variable Environment.

10.4.2, the eval is a direct eval, and it's not strict, so the Lexical
Environment for the eval comes from the with, but the Variable
Environment for the eval comes from the f function scope.

10.5 and 12.2, the var in the eval adds a binding for x in the current
Variable Environment, which is the f function scope, but an assignment
to x in the eval would modify the x in the Lexical Environment, which
is the x established by the 'with'.  12.2 has a sentence noting this

since the x created in f's Variable Environment by the eval is never
assigned any value, the result returned from f is undefined.

More information about the es-discuss mailing list