1 or 3. We have already shot down similiar situations to 2 before. I don't think it is worth bringing this up again.
1 is the least surprise. It is just bad practice, but so is eval and non strict mode in the first place. 3 is fine if you think as if there was a block around the whole thing (except for functions in block in non strict mode). On Fri Feb 14 2014 at 1:42:13 PM, Jeremy Martin <[email protected]> wrote: > > As far as I can see, your #4 and my #1 are exactly the same. How do > you think they differ? > > Actually, on a second read, I don't think they are. I was perhaps more > explicit regarding strict mode, but I think the behavior there was already > clear enough to everyone. :) > > > On Fri, Feb 14, 2014 at 12:14 PM, Allen Wirfs-Brock <[email protected] > > wrote: > > As far as I can see, your #4 and my #1 are exactly the same. How do you > think they differ? > > Allen > > On Feb 14, 2014, at 8:03 AM, Jeremy Martin wrote: > > 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 > > > > > > -- > Jeremy Martin > 661.312.3853 > http://devsmash.com > @jmar777 >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

