Re: variable declarations shadowing named properties on window

On Jan 5, 2012, at 7:08 PM, Cameron McCormack wrote:

> Boris Zbarsky:
>> In any case, the updated text says that if HasBinding returns true then
>> the implementation should call [[GetOwnProperty]] on the global. If this
>> returns undefined, then [[DefineOwnProperty]] is called on the global
>> with the property descriptor: {[[Value]]: undefined, [[Writable]]: true,
>> [[Enumerable]]: true , [[Configurable]]: configurableBindings }.
>> 
>> So now to make var shadow some property that property needs to either
>> return false from HasBinding or return undefined from [[GetOwnProperty]].
> 
> Only if we want to keep them on window.  If we're happy to move them to the prototype then we're safe, I believe.

Keep in bind, that ES5.1 10.5 is an specification, not an implementation.  An actual implementation does not necessarily have an actual HasBinding function.  What the specification fix does is actually formalizing these two statements from the bug report:

3) global function and var declarations always create own properties of the
global object.  If an inherited property of the same name already exists it is
over-ridden with an own property. 
4) The declaration instantiation rules relating to pre-existing bindings
only consider own properties of the global object.  Inherited properties of the
global object have no effect upon the processing of function and var
declarations.
(the first sentence of #3 probably should end with "if the own property does not already exist")


> 
>> Cameron, can GSP properties return undefined from [[GetOwnProperty]] but
>> still do what they should for window.foo and bareword lookups without
>> other things elsewhere breaking?
> 
> They can for window.foo but not for bareword lookups.  window.foo will do a [[Get]], and we could have that return the frame while [[GetOwnProperty]] returns undefined.  That breaks barewords, though, which definitely do use HasBinding and so [[GetOwnProperty]] to determine if the reference can be resolved or not.

I assume by "barewood" you mean an unqualified global reference to foo.  Such a reference calls HasBinding on the global environment record.   This is defined to be equivalent to calling the [[HasProperty]] internal method of the global object.  Note that [[HasProperty]] for normal objects essentially tests the result of [[GetProperty]] for undefined.  window.foo does a [[Get]] on the global object.  The normal definition of [[Get]] also uses [[GetProperty]].  So both window.foo and bareword foo both use [[GetProperty]] in essentially the same way.  I don't see why there would be any difference in their behaviors.

Allen
> 

Received on Friday, 6 January 2012 19:47:53 UTC