[whatwg] Window and WindowProxy

Boris Zbarsky bzbarsky at MIT.EDU
Thu Aug 8 15:40:34 PDT 2013

On 8/8/13 5:05 PM, Ian Hickson wrote:
> I think the problem is that I have no idea what these ES6 terms are or
> what they mean.

OK.  Which terms, exactly?

> Was all this a problem in previous revisions of JavaScript? Or is it some
> new problem caused by some new JavaScript feature?

It's a "problem", as far as it goes, caused by the ability to get 
property descriptors at all.  In the old world there was no way to 
explicitly invoke [[DefineProperty]] or check whether something is 
configurable.  So some things were not observable that are now 
observable, and the ES spec had to define what happens when you observe 

This is not an ES6 issue; ES5 has similar problems, but a bit less 
clarity (e.g. no Proxy objects in ES5,

>>>> "var" needs to be able to define non-configurable properties.
>>>> Proxies don't necessarily offer useful guarantees about being able
>>>> to define such properties on them, and in particular the behavior
>>>> for index/named getters in WebIDL precludes definition of
>>>> non-configurable properties of the corresponding kind on the
>>>> relevant object.
>>> I don't understand what this means, sorry.
>> Hmm.  Which part is unclear?
> I have basically no idea what any of it means. I understand all the
> individual words of that paragraph, but I've no idea what they mean when
> put next to each other in that order. :-) A property is just an entry in
> the bag that is a JS object, what does it mean for it to be or not be
> configurable?

Ah, ok.  So in ES5 there is a concept of a "property descriptor".  There 
is both an internal representation of property descriptors and a way to 
get JS objects that represent a property descriptor: 

See ECMA-262 edition 5 section 8.10 for details on how property 
descriptors work, but fundamentally a property descriptor for an 
existing property describes how it's set up.  A property descriptor can 
also be used to create new properties via Object.defineProperty.

Every property descriptor has two booleans it stores: [[Enumerable]] and 
[[Configurable]].  [[Enumerable]] controls whether the property shows up 
in for..in enumeration.  [[Configurable]] controls how the property 
descriptor for this property can change.  In particular, if 
[[Configurable]] is false, then the values of [[Configurable]], 
[[Enumerable]], [[Get]], [[Set]], and [[Writable]] for this property 
cannot change in the future ([[Value]] can still change if this is a 
value property that is [[Writable]]).

All property manipulation in ES5 and later is defined in terms of 
property descriptors.  For example, the definition of [[Put]] (which is 
the thing that happens on "foo.bar = something") in ES5 section 8.12.5 
does gets the property descriptor and then looking at that descriptor 
and deciding what to do based on that ([[GetOwnProperty]] and 
[[GetProperty]] return property descriptors, somewhat non-obviously).

> A proxy is something that passes incoming requests from one
> object to another object

A Proxy in ES6 is a particular kind of JS object that has pointers to 
two other objects: a target and a handler.  The target is what requests 
get passed to, if desired.  The handler is basically a mapping from MOP 
names to JS functions implementing the relevant MOP operation.

So for example, an object with an indexed getter is defined in WebIDL by 
defining that it has special implementations for three MOP operations: 
[[GetOwnProperty]], [[DefineProperty]], and [[Delete]].  If you wanted 
to implement such an object in JS, there is no way to do this in ES5. 
In ES6, you would create a Proxy whose target is just a vanilla object 
for storing expandos and the proto link and whose handler does the steps 
defined by WebIDL for those three operations.

Note that your description of a proxy above is certainly implementable 
as a Proxy, but a Proxy can also implement other things (again, like 
things with indexed or named getters as currently specced).

See http://people.mozilla.org/~jorendorff/es6-draft.html#sec-8.5 for the 
full-on spec bits.

> what does it mean for a proxy to have a property?

If it returns something other than undefined from [[GetOwnProperty]].

>> Er... That's a cross-site information leak.
> How so? The names of the IDL attributes and methods on Window objects are
> the same on all Window objects (WindowModal notwithstanding), and the
> non-IDL properties aren't enumerable cross-origin.

getOwnPropertyNames returns all own properties, not just enumerable ones.

> "For members that return objects (including function objects), each
> distinct effective script origin that is not the same as the Window
> object's Document's effective script origin must be provided with a
> separate set of objects. These objects must have the prototype chain
> appropriate for the script for which the objects are created (not those
> that would be appropriate for scripts whose script's global object is the
> Window object in question)."

Mmm...  I don't think this works very well for Window.

> (same effective origin)


>> in that situation two different origins become the same origin and the
>> fact that they have different Window objects for the same current window
>> ends up observable.
> Well, what the spec says now is that when the script changes effective
> origin, it also changes its prototypes and so forth, essentially.

Does any UA do this?  I would be somewhat surprised if this were web 
compatible, and even more surprised if it were implementable in practice 
and if any UA wanted to implement it....

> We (the Web community) can change what's allowed and what isn't allowed.
> We do so all the time.

Sure, but changing this makes it very hard to reason about ES, in very 
undesirable ways.  This has been pretty extensively hashed out on 
es-discuss and public-script-coord...

And more to the point it seems unnecessary to throw out useful 
invariants in this case just so we can preserve a particular 
specification device.

>> If an object (in this case a WindowProxy, since that's what the script
>> is working with) ever claims that it has a non-configurable property for
>> some property name, ES requires that it _always_ do that from that point
>> on.
> That's fine. The Window will keep having that property. The WindowProxy
> object's own properties can't be examined

The WindowProxy is the object the script has.  It's the object 
[[GetOwnProperty]] (via Object.getOwnPropertyDescriptor) is called on. 
So the above requirement about the property not disappearing if it's 
non-configurable applies to the WindowProxy.

Which is why WindowProxy can't ever claim to have non-configurable 
properties...  It would violate basic language invariants.


More information about the whatwg mailing list