Four static scoping violations in ES5 sloppy
Mark S. Miller
erights at google.com
Mon Mar 18 09:32:50 PDT 2013
Interesting thread. After all this work trying to figure out what I meant,
I'm sorry to disappoint. Technically, Domenic is right: once we are rid of
"with" and non-strict "eval", #1 and #3 do not technically violate the
degree of static scoping provided by ES5.
So why are they on this list?
Because many who are not already intimately familiar with JS will be
properly outraged at #1 and #3 in non-strict mode, and appreciate that
strict mode cleans up scoping to the extent that it can.
And why does ES5/strict impose these restrictions, when they are not
necessary for the formal criterion?
Because ES5 strict mode, being an opt-in, gave us a rare opportunity to
clean things up in preparation for yet better scoping in ES6. I'm pleased
to report that it mostly turned out that way. Because of #1 and #3, ES5
strict code will be easier to refactor into ES6 modules, where the global
object is finally not on their scope chain. At the time we did this, we
didn't anticipate this specific aspect of ES6, but took the opportunity to
clear the ground.
And because implicit creation of global variables was incredibly hazardous,
turning misspellings into new global variables.
On Mon, Mar 18, 2013 at 6:30 AM, Domenic Denicola <
domenic at domenicdenicola.com> wrote:
> From: Sam Tobin-Hochstadt
> > On Mon, Mar 18, 2013 at 8:40 AM, Andreas Rossberg <rossberg at google.com>
> >> Nothing, but Sam probably meant to write:
> >> if (something_random()) xxx = 7;
> >> xxx; // ReferenceError or not?
> > Right, I was confusing the problem this code describes, which is what I
> think Mark meant, with the problem of the global object being on the scope
> >>> It actually demonstrates how the situation is exactly the same with
> *explicit* global variable creation. Strict mode does nothing to change the
> >>> Similarly, in case 3, the code could be `delete window.xxx` and we
> still cannot statically predict whether there's a `ReferenceError` on the
> subsequent line or not. Again, strict mode does not change the result.
> >> That is true, and the proper answer is that the global object should be
> on the above list as well. Not sure why Mark did not include it.
> > I believe that Mark would distinguish 1-4, which are fixed by strict
> mode, from the global object, which is the remaining issue in ES5.
> Last time this came up:
> it was clarified that the global object is not a static scoping violation,
> since it's the top-most in the scope chain. Thus we know that every binding
> that's not in the nested function environments must be on the global
> object—or not exist.
> That's the essence of my confusion. Cases 1 and 3 do not change things.
> That is, `xxx = 7` versus `window.xxx = 7` doesn't change where we
> determine `xxx` to be: it must be global (if it exists at all). Similarly,
> `delete xxx` versus `delete window.xxx` doesn't change that `xxx` must be
> global or not exist. And strict mode prohibits the former of these two
> forms, but doesn't prohibit the latter, and so seems to have no impact.
> Now, if `with` and sloppy `eval` weren't removed, I could see the
> argument, at least for `delete`:
> but with those two gone (i.e. with 2 and 4 gone), 1 and 3 seem to not
> > But only Mark can answer this for sure.
> Indeed :)
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the es-discuss