I rather hate to say it, but I would've actually expected:
4) Given that the eval'd string doesn't create anything typically
considered a "block", the let binding would survive past the completion of
the eval in non-strict mode:
(function() {
eval("
var answer=42;
let localToEval = true;
");
console.log(answer); // 42
console.log(localToEval); // true
)();
(function() {
"use strict";
eval("
var answer=42;
let localToEval = true;
");
console.log(answer); // ReferenceError: answer is not defined
console.log(localToEval); // ReferenceError: localToEval is not
defined
)();
I'm not necessarily arguing for that behavior, but weighing in since that's
the behavior I would have expected based on existing ES5
strict/non-strict/eval and ES6 let semantics...
On Fri, Feb 14, 2014 at 10:40 AM, Allen Wirfs-Brock
<[email protected]>wrote:
>
> On Feb 14, 2014, at 5:49 AM, André Bargull wrote:
>
> How about this?
>
> let x= 0;
> if (1) eval("let x= 42; alert(x);"); //Is this in its own block?
> alert(x);
>
>
> `eval()` hasn't yet been updated to work with the new lexical declaration
> forms, but I hope the example from above will be evaluated in a new block.
> See https://bugs.ecmascript.org/show_bug.cgi?id=1788 for a related bug
> report.
>
>
> Goood point and this is something I need to specify in the next couple
> weeks so let's look at the alternatives.
>
> First a quick refresher on ES5 era eval.
>
> In ES5, the binding behavior of direct eval differs between strict and
> non-strict modes.
>
> In strict mode, each eval instantiates all declarations in a new
> environment that is immediately nested within the current
> LexicalEnvironment. The scoping behavior is essentially the same as if the
> eval code was the body of an iife that occurred at the same place as the
> eval call. Bindings introduced by the eval code disappear after completion
> of the eval.
>
> In non-strict mode, each eval instantiates all declarations in the current
> VariableEnvironment; that is the most immediately enclosing function or
> global environment. Bindings introduced by the eval code remain accessible
> from that VariableEnvironment after completion of the eval.
>
> For example:
> (function() {
> "use strict";
> eval("var answer=42");
> console.log(answer); // ReferenceError: answer is not defined
> })();
>
> (function() {
> eval("var answer=42");
> console.log(answer); // 42
> })();
>
> For ES6, it makes sense for strict mode evals to behave in this exact same
> way. Each eval takes place in its own environment and no bindings survive
> the completion of the eval.
>
> For ES6, non-strict evals of code containing only var or function
> declarations must have exactly the ES5 behavior in order to maintain
> compatibility. But what about eval code that contains new declaration
> forms (let/const/class) exclusively or in combination with var/function
> declarations? Three possibilities come to mind:
>
> 1) Extend the ES5 semantics to include the new declaration forms. For
> example:
>
> (function() {
> eval("let answer=42");
> console.log(answer); // 42
> })();
>
> 2) Use the strict mode binding semantics if the eval code directly
> contains any of the new declaration forms:
>
> (function() {
> eval("
> var answer=42;
> let forceSeprateEnvironment = true;
> ");
> console.log(answer); // ReferenceError: answer is not defined
> })();
>
> 3) Combination. use ES5 non-strict binding semantics for var/function
> declarations but place let/const/class bindings into a per eval environment:
>
> (function() {
> eval("
> var answer=42;
> let localToEval = true;
> ");
> console.log(answer); // 42
> console.log(localToEval); // ReferenceError: localToEval is not
> defined
> )();
>
>
> It would certainly be possible to specify #1, but I don't like it. Other
> than for the global environment it would be cleaner if the new block
> scope-able declarations were never dynamically added to the environment.
>
> I think either #2 or #3 is plausible. #2 is a simpler story but
> introduces a refactoring hazard. If you have some existing eval code that
> defines some "global" functions or variables, then simply adding a
> let/const/class declaration to the eval code ruins those global
> declarations.
>
> I prefer the simplicity of #2, but I also worry about the WTF impact it
> might have on evolving existing code.
>
> Can we get away with #2, or are we going to have to go with #3? Are there
> other alternatives?
>
> Allen
>
>
>
>
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
>
>
--
Jeremy Martin
661.312.3853
http://devsmash.com
@jmar777
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss