The global object should not be the "global scope instance object"

Brendan Eich brendan at
Thu Jan 26 11:51:09 PST 2012

> Andreas Rossberg <mailto:rossberg at>
> January 26, 2012 11:26 AM
> On 26 January 2012 17:47, Allen Wirfs-Brock<allen at>  wrote:
>> On Jan 26, 2012, at 3:01 AM, Andreas Rossberg wrote:
>>> Overlapping imports? That's the first time I hear about that. That
>>> might be rather difficult, given that modules are recursive.
>> It's just something I threw in that the module champions need to weigh in on.  It seems desirable to allow things like:
>> <script>
>> import {create} from "@names";
>> const foo = create();
>> </script>
>> <script>
>> import {create} from "@names";

(Just in case anyone is worrying, I believe (or assert) that the 
destructuring here is not required. Just |import create from "@name";| 
would do. Also, we are eschewing plurals in built-in module names, so 
> Module scoping is difficult, especially if you want a semantics that
> can be decided efficiently. Moreover, shadowing and recursion (and
> every ES6 scope is recursive) don't go together well. And things get
> even more interesting with "import *".

These are important points, agreed.

> I still like the idea of cross-script shadowing (aka nested scopes),
> but one concern was that it is not clear what names would be in scope
> for, say, a piece of JS code in a random HTML attribute somewhere on
> the page.

We could say event handler attributes are scoped by the most-nested 
scope -- the scope due to the last <script> element that was closed 
before the element with the event handler attribute was processed.

This means generated scripts (document.write or DOM create* calls) do 
not see the generating script's let and const bindings.

But it's worse than that. What about <script async src="..."> (or the 
HTML4-era, not fully supported on all browsers <scriptdefer src="...">? 
Async scripts are not supposed to have global effects other than 
defining functions that the page or app author ensures won't be called 
till after all content (or at least all scripts, or at least all of the 
needed async scripts) has finished loading. In what scope do async 
script let/const top-level bindings go?

The situation is messy enough that I question the win of nesting scopes. 
True, a global object subject to async-loaded effects is no picnic, but 
it is the devil we know. And these var and function bindings, however 
racy, are not supposed to be lexical, as let and const are.


More information about the es-discuss mailing list