Re: Changes in chrome JS code due to ES6 global lexical scope
Good catch and thanks for the correction! The take-home from the example is that: due to the global lexical scope, a TDZ error could arise later due to newly introduced bindings. On Thu, Sep 17, 2015 at 7:34 PM, Boris Zbarskywrote: > On 9/17/15 8:26 PM, Shu-yu Guo wrote: > >> The first call to f() does not throw. >> > > It actually does, because the bareword lookup for "x" fails. You get > "ReferenceError: x is not defined". > > If you replaced "x" with "window.x" or "self.x" or "this.x" or something I > think you'd get the behavior you describe. > > -Boris > > ___ > dev-platform mailing list > dev-platform@lists.mozilla.org > https://lists.mozilla.org/listinfo/dev-platform > -- shu ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Changes in chrome JS code due to ES6 global lexical scope
Shu-yu Guo wrote: Good catch and thanks for the correction! The take-home from the example is that: due to the global lexical scope, a TDZ error could arise later due to newly introduced bindings. So for that I guess the code would have to look like this? var x; function f() { dump(x); } f(); // prints undefined f(); // throws TDZ error? let x = 42; -- Warning: May contain traces of nuts. ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Changes in chrome JS code due to ES6 global lexical scope
On 17/09/15 19:59, Shu-yu Guo wrote: > Because until now, our global 'let' semantics have been identical to > those of 'var', I have already landed a patch that mass replaces global > 'let' with 'var' as part of bug 1202902. I think someone should make you a "var is the new let" t-shirt... Gerv ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Changes in chrome JS code due to ES6 global lexical scope
I think that would fail as well, because the let would be shadowing the global x, which isn't allowed. On Sep 18, 2015 2:25 PM, "Neil"wrote: > Shu-yu Guo wrote: > > Good catch and thanks for the correction! The take-home from the example is >> that: due to the global lexical scope, a TDZ error could arise later due >> to >> newly introduced bindings. >> >> So for that I guess the code would have to look like this? > > > var x; > function f() { dump(x); } > f(); // prints undefined > > > > f(); // throws TDZ error? > let x = 42; > > > -- > Warning: May contain traces of nuts. > ___ > dev-platform mailing list > dev-platform@lists.mozilla.org > https://lists.mozilla.org/listinfo/dev-platform > ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Changes in chrome JS code due to ES6 global lexical scope
Hello all, We are in the process of implementing the global lexical scope per ES6. This changes the semantics of global level 'let' and 'const' bindings from our non-standard semantics to standard semantics. Currently, global 'let' and 'const' bindings introduce properties onto the global object. Global 'let' behaves identically to 'var', and global 'const' is like 'var', with the exception that the property it introduces is read-only. Since they behave essentially like 'var', they can be redeclared and there is no TDZ (i.e., you can use them before their declarator is reached, resulting in an undefined). In ES6, this changes. 1. Global 'let' and 'const' are no longer properties on the global object. They go into a separate global lexical scope. 2. Global 'let' and 'const' may not be redeclared at the global level with 'let', 'const', or 'var'. 3. Global 'let' and 'const' are subject to temporal dead zone (TDZ) semantics. If they are referenced before their declarator is executed, a ReferenceError is thrown. For example, dump(x); // will throw instead of print undefined. let x = 42; 4. The global lexical scope is extensible. This means dynamic scope (lol!): function f() { dump(x); } f(); // prints undefined let x = 42; f(); // prints 42 As you can imagine, these changes break all our chrome code. Almost all the errors are due to 1) and 2). Due to 1), there are many places where code expects 'let' and 'const' bindings are expected to be properties. Cu.import is a common offender: Foo.jsm: const SOME_CONSTANT = 42; foo.js: // SOME_CONSTANT isn't a property on the global scope returned by Cu.import const { SOME_CONSTANT } = Cu.import("Foo.jsm", {}) Due to 2), there are thousands of places where we redeclare Ci, Cc, Cu, etc. Many tests redeclare 'let' and 'const' bindings. Test harnesses also like to inject code with 'let'. I am in the process of slowly fixing the world. Because until now, our global 'let' semantics have been identical to those of 'var', I have already landed a patch that mass replaces global 'let' with 'var' as part of bug 1202902. Because there is no direct syntactic replacement for 'const', I am combing through the code on a case by case basis. For Firefox devs, I ask 2 things: 1) For bindings expected to be properties on the global scope, please do that explicitly with |this.foo = ...| or 'var' and stop using 'let' and 'const'. 2) Understand the semantics of Cu.import. From reading the code, this seems commonly misunderstood. The API is |Cu.import(path, targetObj)|. In pseudocode, what Cu.import does is: ... executes script pointed to path ... for (symbol of jsmGlobalScope.EXPORTED_SYMBOLS) { targetObj[symbol] = jsmGlobalScope[symbol]; } return jsmGlobalScope; That is, Cu.import's return value is the *entire global scope* of the JSM. It isn't targetObj. It doesn't respect EXPORTED_SYMBOLS. You can get anything you want out of the global scope of the JSM. The relevant bugs are bug 1202902 and bug 589199. Please reach out on IRC if you have questions. -- shu ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Changes in chrome JS code due to ES6 global lexical scope
On 9/17/15 8:26 PM, Shu-yu Guo wrote: The first call to f() does not throw. It actually does, because the bareword lookup for "x" fails. You get "ReferenceError: x is not defined". If you replaced "x" with "window.x" or "self.x" or "this.x" or something I think you'd get the behavior you describe. -Boris ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Changes in chrome JS code due to ES6 global lexical scope
Shu-yu Guo wrote: 4. The global lexical scope is extensible. This means dynamic scope (lol!): function f() { dump(x); } f(); // prints undefined let x = 42; f(); // prints 42 Would you mind clarifying what this is supposed to demonstrate? It looks to me that this is demonstrating TDZ semantics, and under ES6 the first call to f() will throw. -- Warning: May contain traces of nuts. ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Changes in chrome JS code due to ES6 global lexical scope
On Thu, Sep 17, 2015 at 5:18 PM, Neilwrote: > Shu-yu Guo wrote: > > 4. The global lexical scope is extensible. This means dynamic scope (lol!): >> >> >> function f() { dump(x); } >> f(); // prints undefined >> >> >> >> let x = 42; >> f(); // prints 42 >> >> >> Would you mind clarifying what this is supposed to demonstrate? It looks > to me that this is demonstrating TDZ semantics, and under ES6 the first > call to f() will throw. > The first call to f() does not throw. These are two separate tags, and during the execution of the first