On Jan 26, 2012, at 11:51 AM, Brendan Eich wrote:

>> Andreas Rossberg <mailto:rossb...@google.com>
>> January 26, 2012 11:26 AM
>> ...
> 
>> 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.

Why closed? All declarations within a Program are instantiated before 
evaluating any code in its <script> element so generated scripts should be able 
to reference the bindings for those declarations.  However, if such reference 
are actually evaluated they might fall into the bindings' temporal dead zones. 


> 
> 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.

Is this a specified restriction?  If it is, I haven't been able to find it 
anywhere.  

> In what scope do async script let/const top-level bindings go?

If it is a specified restriction then I would think that  when a browser ES 
implementation actually processes such scripts they should reject any top level 
declarations other than functions. Regardless, it seems likely that 
indeterminate load ordering problems created by  HTML need to be solved at that 
level.  Why don't script elements have a dependency attribute:

<script src="someLib.js"  type="application/javascript" async="async" 
id="lib1"></script>
<script src="anotherLib.js"  type="application/javascript" async="async" 
id="lib2"></script>
<script src="baseApp.js"  type="application/javascript" async="async" id="base" 
after="lib1"></script>
<script src="extraApp"  type="application/javascript" async="async" 
after="lib2,base"></script>

> 
> 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.

I think these are the alternatives we currently have under consideration:

SQ (status quo):  every top level declaration are all implemented as properties 
of the global object
STL (Single Top Level):  All script blocks share a declarative environment for 
new (not var and function) kinds of declarations that shadows the global 
object. Scripts with duplicate declarations are rejected.
TLpSi (Top Level per script, isolated):  Each script block has a declarative 
environment for new (not var and function) kinds of declarations.  Each shadows 
the global object but are invisible to each other.
TLpSn (Top Level per script, nested):  Each script block has a declarative 
environment for new (not var and function) kinds of declarations.  Each is 
logically nest within and shadows the previously processed script

STL is what I'm proposing.  I think that TLpSn corresponds to  Andreas 
preference.  One way to look at TLpSn is that uses shadowing to accept the 
duplicate declarations that STL rejects.  This seems like a problem that is 
better addressed by using modules. TLpBn also raises issues like, what scope 
does an indirect eval use?  I haven't head anyone recently advocating for 
TLpSi.  You can achieve almost the same thing using SQ by wrapping a block 
around each script body.

In general, when I start think about the ways that lexical declarations in 
separate scripts might interact I run into issue that are probably best 
resolved using modules. I'm inclined to favor the simpler solution and leave it 
to modules to deal with managing actual interdependencies cases.

Allen
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to