Strict mode eval

Juriy Zaytsev kangax at gmail.com
Tue May 10 10:58:33 PDT 2011


On Tue, May 10, 2011 at 1:16 PM, Andreas Rossberg <rossberg at google.com>wrote:

> I'm a bit puzzled regarding the meaning of "use strict" in the context
> of higher-order uses of eval.
>
> Consider the following program. What is the expected result of the latter
> calls?
>
> ---------------------
> var x = 3
>
> function call_eval() { x = 3; eval("var x = 4"); return x }
> function call_eval_strict() { "use strict"; x = 3; eval("var x = 4");
> return x }
>
> function get_eval() { return eval }
> function get_eval_strict() { "use strict"; return eval }
>
> function call_f(f) { x = 3; f("var x = 4"); return x }
> function call_f_strict(f) { "use strict"; x = 3; f("var x = 4"); return x }
>
> call_eval()  // 4
> call_eval_strict()  // 3
>

This is correct.


>
> call_f(eval)  // 4
> call_f(get_eval())  // 4
> call_f(get_eval_strict())  // ?
>

The last one should return 4 as well. There's no difference between `eval`,
`get_eval()`, and `get_eval_strict()` in this context. All of them are
essentially a reference to a built-in, global `eval` function. Strict mode
only affects calling behavior of `eval`. The retrieval of `eval` object is
still the same.

But something else comes into play here, and that something is indirect eval
call.


>
> call_f_strict(eval)  // ?
> call_f_strict(get_eval())  // ?
> call_f_strict(get_eval_strict())  // ?
>

When `call_f_strict` executes and `eval` is called from within it, it is
actually an indirect eval call. Why? Because the reference name is not
`eval`, but `f` and so it doesn't satisfy direct eval call requirement (see
http://es5.github.com/#x15.1.2.1.1)

In ES5 indirect eval calls execute in global execution context (
http://es5.github.com/#x10.4.2) and so all 3 last calls actually end up
executing `var x = 4` in global scope (overwriting global `x`).

You can see that if you were to create local `x` variable in `call_f_strict`
that `x` would be unaffected by eval calls.

function call_f_strict(f) {
  "use strict";
  var x = 3;
  f("var x = 4");
  return x; // should return `3`, since `x = 4` was executed outside of this
local scope
}

For more on indirect eval calls —
http://perfectionkills.com/global-eval-what-are-the-options/

[...]

-- 
kangax
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110510/a16052b7/attachment.html>


More information about the es-discuss mailing list