The global object as the "global scope instance object"

Brendan Eich brendan at mozilla.org
Mon Jan 23 09:39:25 PST 2012


> Andreas Rossberg <mailto:rossberg at google.com>
> January 23, 2012 5:54 AM
> On 22 January 2012 23:46, Gavin Barraclough<barraclough at apple.com>  wrote:
>> On Jan 20, 2012, at 4:23 PM, Allen Wirfs-Brock wrote:
>>> I'm not yet convinced that you need to publicly expose such global object
>>> properties accessor properties.  I think it is possible to hide the
>>> mechanisms.
>> I'm strongly inclined to agree with this sentiment – engine implementors
>> might choose internally to utilize accessors in their implementations, but
>> from a user perspective it seems to make much more sense that these remain
>> as regular data properties.  It is worth bearing in mind that 'const' is
>> already available outside of strict mode and we need to be considerate of
>> any breaking changes we make to existing semantics.
>
> Sigh. This may be exactly the reason why I am deeply sceptical that
> backporting ES6 features to classic mode is a wise move. Now we don't
> just have to stay backwards compatible with broken ES5 features, we
> even have to stay backwards compatible with broken ES5 non-features?
> Even in strict mode?
>
> Harmony was supposed to be based on strict mode for a reason.

Hang on -- I think Gavin may have stated things in a way that set the 
cat among pigeons unnecessarily. We agreed (at least Gavin and I) at the 
f2f to try to bring our const and function-in-block implementations in 
line with non-strict ES6 in the version-free opt-in model toward which 
we're striving.

In this light I do not think we should preemptively concede anything to 
breaking changes of existing *implementation* semantics.

OTOH the rest of Gavin's mail invoked existing implementations (Firefox 
in particular) more for intuitive non-strict appeal than as binding 
precedent, if I read Gavin right.

On *how* to implement the suggested semantics, I do see disagreement. 
Indeed I hope we do not need to introduce not-yet-defined as a value 
state in the object model. But the user-facing non-strict semantics 
should be separable.


>>   (We could define
>> incompatible semantics for strict-mode only, but this would likely lead to a
>> confusing divergence in semantics for users – it could be horribly confusing
>> if const variables in non-strict code were to be implemented as data
>> properties whilst those in strict code were defined as accessor properties).
>>
>> alert('value' in Object.getOwnPropertyDescriptor(this, 'x'));
>> alert(Object.getOwnPropertyDescriptor(this, 'x').writable === true);
>>
>> alert(Object.getOwnPropertyDescriptor(this, 'x').value);
>> x = 1;
>> alert(Object.getOwnPropertyDescriptor(this, 'x').value);
>> const x = 2;
>> alert(Object.getOwnPropertyDescriptor(this, 'x').value);
>> x = 3;
>> alert(Object.getOwnPropertyDescriptor(this, 'x').value);
>>
>> This script tests the presence and writability of a property on the global
>> object, and the effect of attempting to assign to it in non-strict code.  It
>> demonstrates a non-const var behaving as a regular non-writable property in
>> non-strict code.
>>
>> On FireFox the above script outputs "true, false, undefined, undefined, 2,
>> 2", which to my mind makes a lot of sense.  It perfectly matches, as far as
>> one can test, any other regular non writable property that you could create
>> on an object (of course there it not normally the opportunity to split
>> creation and initialization of a non-writable property).
>
> I disagree completely. This is the current V8 semantics as well, but
> it does _not_ make sense.
>
> You observe that the value of a const is changing in the middle of
> your program. That fundamentally violates const semantics, and is
> incompatible with the idea of guards on let as well.

Yes, we agree to all that for strict code (ES5 or above), but this is 
non-strict code. In non-strict code, implementations have already 
violated const semantics, and we have not added guards yet.
>
> Furthermore, the property descriptor tells you that the property is a
> writable data property,

No -- false is the second value alerted.

>   but you cannot write it (e.g. replacing "x =
> 1" with "this.x = 1"). That violates the object model.
>
> In other words, the current behaviour breaks both scoping and objects semantics.

Non-strict or really pre-strict implementations broke scoping semantics 
-- no temporal dead zone. Whether we can retroactively force the new 
semantics on any JS that worked with the old scoping semantics remains 
to be seen.

Object semantics, I think you misread the alert output. Or did I?


>> This behaviour is also sensibly consistent with that for let and var.
>>   Running the above script, changing 'const' to 'var'
>> outputs "true, true, undefined, 1, 2, 3" (indicating the property is
>> writable, and all assignments succeed), and for 'let' currently also
>> outputs "true, true, undefined, 1, 2, 3" on FireFox.  To my mind this
>> behaviour should probably change slightly.  With a temporal dead zone
>> implemented I would expect an attempt to [[DefineOwnProperty]] to an
>> uninitialized value to be rejected (though I would not expect an exception
>> to be thrown from non-strict code) so I would expect the output for 'let' to
>> be "true, true, undefined, undefined, 2, 3" (the assignment of 'a' silently
>> fails leaving the value unchanged).
>
> More importantly, an attempt to [[Get]] an uninitialized property also
> has to be rejected. Both requires proliferating the entire notion of
> being uninitialized into the object model. To be coherent, you'd also
> have to be able to reflect on it through property descriptors, make it
> available to proxies, and so on. I see no good reason why we should go
> there.

Agreed. And for non-strict code if we choose to keep the non-throwing 
behavior, we do not have to. We do however therefore have to allow a 
const to be read before initialized, with value undefined -- but only 
for non-strict code.

This is future-hostile to guards, or really, we kick the can down the 
road a bit and evangelize strict mode. If and when we add guards, we can 
either break scoping semantics backward compatibility, or require strict 
opt in.

/be


More information about the es-discuss mailing list