Prev: seethis VERY DIFFERENT
Next: regex help?
From: Asen Bozhilov on 4 Dec 2009 09:35 Dmitry A. Soshnikov wrote: > Asen Bozhilov wrote: > Well, it does, and exactly "inherits" but not "borrows" as in non- > strict mode, when `LexicalEnvironment` of the calling context becomes > `LexicalEnvironment` of the eval context. In strict mode > `LexicalEnvironment` of the calling context saves in `outer` property > of the newly created `DeclarativeEnvironment` for eval context. > > > What is properly behavior of code like that: > > > (function(){ > > var v; > > eval('window.alert(v);'); //undefined or Reference Error? > > window.alert(v); //undefined > > > }()); > > `undefined` as will be found in `outer` lexical environment. Ok understood. But what will be happen with function declaration, function statement and function expression in code passed to `eval' in strict mode. What will be refer internal [[scope]] property of these objects? e.g. var v = true; eval('var v = false; (function(){window.alert(v)})();'); //true or false. That is the question :~) Regards.
From: Dmitry A. Soshnikov on 4 Dec 2009 10:18 On Dec 4, 5:35 pm, Asen Bozhilov <asen.bozhi...(a)gmail.com> wrote: > Dmitry A. Soshnikov wrote: > > Asen Bozhilov wrote: > > Well, it does, and exactly "inherits" but not "borrows" as in non- > > strict mode, when `LexicalEnvironment` of the calling context becomes > > `LexicalEnvironment` of the eval context. In strict mode > > `LexicalEnvironment` of the calling context saves in `outer` property > > of the newly created `DeclarativeEnvironment` for eval context. > > > > What is properly behavior of code like that: > > > > (function(){ > > > var v; > > > eval('window.alert(v);'); //undefined or Reference Error? > > > window.alert(v); //undefined > > > > }()); > > > `undefined` as will be found in `outer` lexical environment. > > Ok understood. But what will be happen with function declaration, > function statement and function expression in code passed to `eval' in > strict mode. What will be refer internal [[scope]] property of these > objects? > > e.g. > > var v = true; > eval('var v = false; (function(){window.alert(v)})();'); //true or > false. That is the question :~) > Should be `false`, abstractly it looks like: // global's LE LexicalEnvironment = { outer: null, EnvironmentRecord: { v: true } } // eval's LE LexicalEnvironment = { outer: globalLE, EnvironmentRecord: { v: false } } // anonymous FE LexicalEnvironment = { outer: evalLE, EnvironmentRecord: {} } So, `Identifier Resolution` (10.3.1) which calls `GetIdentifierReference` (10.2.2.1) has recursive analysis of `LexicalEnvironment` depending on `outer` property starting from `LexicalEnvironment` of the anonymous FE. P.S.: that's abstract algorithm independent on concrete type of the environment record (declarative, object). /ds
From: kangax on 4 Dec 2009 13:04 Asen Bozhilov wrote: > Dmitry A. Soshnikov wrote: >> Asen Bozhilov wrote: > >> Well, it does, and exactly "inherits" but not "borrows" as in non- >> strict mode, when `LexicalEnvironment` of the calling context becomes >> `LexicalEnvironment` of the eval context. In strict mode >> `LexicalEnvironment` of the calling context saves in `outer` property >> of the newly created `DeclarativeEnvironment` for eval context. >> >>> What is properly behavior of code like that: >>> (function(){ >>> var v; >>> eval('window.alert(v);'); //undefined or Reference Error? >>> window.alert(v); //undefined >>> }()); >> `undefined` as will be found in `outer` lexical environment. > > Ok understood. But what will be happen with function declaration, > function statement and function expression in code passed to `eval' in Technically, there are no function statements in ES5. Function declarations are still /SourceElement/'s and so are only allowed in /Program/ and /FunctionBody/. What happens to "Function Statements" is still *not formally specified*. As a matter of fact, if you look at Chapter 12, you can see this note: "NOTE Several widely used implementations of ECMAScript are known to support the use of FunctionDeclaration as a Statement. However there are significant and irreconcilable variations among the implementations in the semantics applied to such FunctionDeclarations. Because of these irreconcilable difference, the use of a FunctionDeclaration as a Statement results in code that is not reliably portable among implementations. It is recommended that ECMAScript implementations either disallow this usage of FunctionDeclaration or issue a warning when such a usage is encountered. Future editions of ECMAScript may define alternative portable means for declaring functions in a Statement context." I've been meaning to add this excerpt to NFE article (to func-statements section � http://yura.thinkweb2.com/named-function-expressions/#function-statements) for a while now, but haven't had time yet. > strict mode. What will be refer internal [[scope]] property of these > objects? > > e.g. > If you're talking about strict mode, it's a good idea to reflect it in code, by adding use strict directive � `"use strict";` � to either beginning of code or beginning of eval'ed string ;) > var v = true; > eval('var v = false; (function(){window.alert(v)})();'); //true or > false. That is the question :~) ES3: false ES5: false ES5-strict: false But it would probably be more informative to change this example slightly: var v = true; eval('"use strict"; var v = false; alert(v);'); alert(v); In this case, you would actually see the difference between ES5 and ES5-strict: ES3: false, false ES5: false, false ES5-strict: false, true <-- note that outer `v` is not affected I've heard rumors (from more or less reliable sources) that ES5 was approved yesterday, but haven't seen any official announcement yet. -- kangax
From: Asen Bozhilov on 4 Dec 2009 16:06 Dmitry A. Soshnikov wrote: > Should be `false`, abstractly it looks like: > > // global's LE > LexicalEnvironment = { > outer: null, > EnvironmentRecord: { > v: true > } > > } > > // eval's LE > LexicalEnvironment = { > outer: globalLE, > EnvironmentRecord: { > v: false > } > > } > > // anonymous FE > LexicalEnvironment = { > outer: evalLE, > EnvironmentRecord: {} > > } Thank you for response. If i properly understood you answer, internal [[scope]] property of anonymous function expression refer `EnvironmentRecord` created from eval lexical environment. So i can form *closure* in this way in code passed to `eval'. var global = this, f; eval([ '"use strict";', 'global.f = function(){', '/*function body*/', '};' ].join('')); window.alert(f);
From: Dmitry A. Soshnikov on 5 Dec 2009 06:42
On Dec 4, 9:04 pm, kangax <kan...(a)gmail.com> wrote: [...] > > Technically, there are no function statements in ES5. Function > declarations are still /SourceElement/'s and so are only allowed in > /Program/ and /FunctionBody/. > > What happens to "Function Statements" is still *not formally specified*. > As a matter of fact, if you look at Chapter 12, you can see this note: > > "NOTE Several widely used implementations of ECMAScript are known to > support the use of FunctionDeclaration as a Statement. However there are > significant and irreconcilable variations among the implementations in > the semantics applied to such FunctionDeclarations. Because of these > irreconcilable difference, the use of a FunctionDeclaration as a > Statement results in code that is not reliably portable among > implementations. It is recommended that ECMAScript implementations > either disallow this usage of FunctionDeclaration or issue a warning > when such a usage is encountered. Future editions of ECMAScript may > define alternative portable means for declaring functions in a Statement > context." > Yeah, already discussed regarding ECMA-262-3. And nevertheless, implementation of Spidermonkey (and other newer *monkeys) still seems to me more logical (e.g. for if-else statements) regardless specification. I don't see the big sense in words they say "an ExpressionStatement cannot start with the `function` keyword because that might make it ambiguous with a FunctionDeclaration"? If it's in statement position let's treat is as special FD which won't be created on entering the context, but in runtime like FE and let's call it Function Statement (FS). I thought ECMA-262-5 should borrow this Spidermonkey's `FS`s. But no, they again have restriction for FD-style function's in statements and I don't see the useful goal from it. ;) /ds |