The global object as the "global scope instance object"

Brendan Eich brendan at mozilla.org
Tue Jan 24 09:49:00 PST 2012


> Andreas Rossberg <mailto:rossberg at google.com>
> January 24, 2012 2:37 AM
> On 23 January 2012 19:25, Brendan Eich<brendan at mozilla.org>  wrote:
>> Andreas Rossberg<mailto:rossberg at google.com>:
>>> V8 currently allows
>>>
>>>    var w = 1; w = 2; print(w); const w = 3
>>>
>>> which will output 2. The idea most likely was that const should behave
>>> like var. This, and other, similar examples clearly have to break if
>>> should const become official in classic mode, so the compatibility
>>> argument may not carry far.
>> SpiderMonkey:
>>
>> js>  var w = 1; w = 2; print(w); const w = 3
>> typein:19: TypeError: redeclaration of var w:
>> typein:19: var w = 1; w = 2; print(w); const w = 3
>> typein:19: ....................................^
>>
>> js>  var w = 1
>> js>  const w = 3
>> typein:22: TypeError: redeclaration of var w
>
> However:
>
> js>  const w = 3; var w = 1; print(w);
> 3

This follows from var not disturbing a pre-existing binding. Or so we 
thought long ago when adding const, but that was years before const as 
initialize-only-and-at-most-once let.
>> Why does V8 do something else, do you know the impetus for diverging?
>
> No, unfortunately I don't know the full history there. I can try to find it out.
>
> But just to be obnoxious, with Firefox:
>
> print(c);
> Object.defineProperty(this, 'c', {value: 1});
> print(c);
> const c = 2;
> print(c);
> =>  undefined 1 2

You bet -- const does redefine the global property, unlike var. This is 
not something we propose for standardization, of course!
> Or even:
>
> print(c);
> Object.defineProperty(this, 'c', {value: 1, writable: true});
> print(c);
> c = 2;
> print(c);
> const c = 3;
> print(c);
> =>  undefined 1 2 3
>
> Apparently, FF avoids breaking the object model only for the price of
> keeping the non-writable const property configurable until the actual
> initialization -- effectively breaking const completely.

More fun:

js> function f(k) {
   for (var i = 0; i < k; i++) {
     const j = i*i;
     a.push(j);
   }
}
js> a = []
[]
js> f(10)
js> a
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

SpiderMonkey const has never been initialize-at-most-once. Some people 
claim to like this, but we are going to try breaking it in favor of ES6.

> Consequently, I maintain my claim that it is impossible to reconcile
> sane let/const semantics with the idea of having toplevel bindings
> represented as data properties on the global object.

I agree. For ES4 we equated let to var at top-level, a mistake. For ES6 
IIRC you have proposed an implicit block scope at top level (of 
functions at least, I don't see why not programs as well), whereby let 
and const bind lexically. Only var and function make global object 
properties.

>   If there is some
> trick for "hiding" accessor semantics that doesn't break the object
> model then I'd be really interested in seeing it. :)

Me too.

/be
>


More information about the es-discuss mailing list