The global object as the "global scope instance object"

Andreas Rossberg rossberg at google.com
Fri Jan 20 05:55:21 PST 2012


>From the TC39 notes:
> DaveH:  What if there are duplicate top-level bindings?
> MarkM:  Top-level let should behave as much as possible the same as
> concatenated scripts.

It's my claim that it is impossible to reconcile all of the following
three goals in a way that is even remotely sane:

1. Top-level bindings are aliased as data properties of the global object.
2. Top-level bindings allow redefinition of existing properties of the
global object.
3. Top-level let/const have a temporal dead-zone.

Abandoning (3) essentially means abandoning a reasonable "const"
semantics for the toplevel (and future hostile to guards), so we don't
want to do that. (For V8, we had long struggles with defining and
implementing a const for the (current notion of) top-level that
actually makes any sense. We failed.)

Hence, I would like to suggest another, more moderate idea for a
global scope reform: treat the global object similar to a module
instance objects. That is:

- Top-level bindings (other than var) are reflected as accessor
properties on the global object.
- They are defined on the global object before the script starts executing.
- Their getters/setters simply delegate to the bound variables.
- For const bindings, there are no setters.
- These properties are non-configurable.
- Unlike a module instance object, the global object is extensible
(multiple scripts!).

This disallows lexical bindings to redefine existing non-configurable
properties of the global object (including ones reflecting bindings
from earlier scripts), which is checked before the script starts
executing. Likewise, let/const-defined properties cannot later be
deleted from the global object.

Apart from that, not much should change in practical terms. You should
pretty much be able to replace var with let. At the same time, static
scoping actually is maintained, and there is no issue with temporal
dead zones. Moreover, concatenating scripts would not affect the
meaning or validity of bindings, AFAICS.

Regarding scope pollution, I think this is best solved by making the
global object be a fresh empty object that has the object containing
all primordials as its prototype. Overriding is allowed according to
the standard defineProperty semantics. No special rules necessary.

/Andreas


More information about the es-discuss mailing list