Figuring out the behavior of WindowProxy in the face of non-configurable properties

Boris Zbarsky bzbarsky at
Wed Jan 14 17:03:19 PST 2015

On 1/14/15 7:40 PM, Ian Hickson wrote:
> I don't understand what you mean by "expressible in ES terms".

The behavior of ES objects is expressed in terms of various internal 
methods.  That's what you have to do to express what an ES object does.

> No. WindowProxy isn't an ES Proxy.

It's an ES object.

> It is indistinguishable from the Window object.

It's distinguishable in various ways, including things like "if I get 
this property from it in 5 seconds, will I get the same value as from 
the Window?"  The answer to that is "maybe not".

> When the WindowProxy changes what it's pointing at,
> it's exactly as if the browser had reached in and changed every
> WindowProxy that pointed to the former and made it point to the latter.

You say "every WindowProxy", but in practice in an ES implementation you 
have some object, it has some internal methods.  This is the last time 
I'm bothering to go through this with you, since clearly we're getting 
nowhere, as I said in

> I don't understand how that follows.

I don't understand how you can possibly not understand, except via your 
assumption that a WindowProxy is not an object.

>> I think you misunderstand what the invariant is.
> Maybe. Please elaborate.

The internal methods of every object must have behavior that preserves 
the invariants.

For ES proxies, the internal methods are defined in the spec in a way 
that preserves the invariant.

For other ES objects they are also defined in the spec.

ES also allows other "exotic objects" that define some other behavior 
for those internal methods, but requires that the invariants be preserved.

>> It doesn't matter.  The user sees the WindowProxy, not the Window.
> No. What the author has is a WindowProxy, but in every sense it acts like
> a Window.

You mean in every sense except what property values you'll get five 
seconds from now.

But again, we agree the author has a WindowProxy.  Good.

>> After you navigate, you still have the same WindowProxy (e.g.
>> .contentWindow returns something that is === to the thing you had before
>> you navigated).
> You have no way to actually test this. Since every reference to the old
> Window is now a reference to the new Window, you have no way to test if
> the WindowProxy references something new.

=== on objects tests object identity.  It's not affected by internal 
methods in any way.  Therefore, if === returns true then you actually 
have the same object.

>     // part 1
>     let a = {};
>     let b = {};
>     let c = a;
>     // part 2
> = 1;
>     // part 3
>     c = b;
>     // part 4
>     console.log(;
> Is it surprising that the log doesn't log "1"?

None of this affects the invariants involved.

> This is what is going on here, except that part 3 is done by the browser.

No, because in the code above if I do |var d = c;| then the d won't 
change in part 3.  Having an object with sane internal methods here is 
really much simpler than magic "update all the references" behavior. 
But again, I've said this to you numerous times.

Let me try it again: the fact that the definition in the HTML spec has 
not lead to interop is not an accident.  It's not something browsers can 
sanely achieve interop on because it involves handwavy magic that they 
are extremely likely to interpret differently.  On the other hand, 
defining a single object with internal methods that do what you want 
would be _very_ clear to an DOM or JS engine implementor.

> It looks and quacks like a Window.

No, it, doesn't, see above.

> It turns out that it does have such a type. WindowProxy is it. I agree
> that that makes it a special snowflake.

My point is that this special snowflake is unnecessary and confusing.


More information about the es-discuss mailing list