1

Background

By reading the Web IDL spec section that relates to creating new platform objects, we know that when the global object is created its [[prototype]] is set to the global interface object's instance prototype object (which was created previously, when the interface object was created).

By looking at the section describing how interface prototype objects are created, we see that the global object's [[prototype]] gets its [[prototype]] set to the named properties object.

That object, in turn, gets [[prototype]] linked to whatever the global interface inherited from.

As seen, the prototype chain defined for the global object by the IDL and HTML specs, is as follows:

window -> Window.prototype -> WindowProperties (the *named properties object*) -> EventTarget.prototype -> Object.prototype -> null

Question

Firefox creates that exact prototype chain, but Chrome seems to add one extra copy of the global object to the chain. If you console.dir(window) and look at the console in Chrome, it shows:

window -> window -> Window.prototype -> WindowProperties (the *named properties object*) -> EventTarget.prototype -> Object.prototype -> null

Interestingly, console.dir(Object.getPrototypeOf(window)) in Chrome will indeed log Window.prototype, so the oddity is that first "global object copy" added to the start of the chain.

Why does Chrome do that, and can that behavior be found in any spec?

Magnus
  • 6,791
  • 8
  • 53
  • 84
  • A longer chain on this and similar topics can be seen here (for those interested): https://chat.stackoverflow.com/rooms/250856/room-for-magnus-and-bergi-web-idl – Magnus Jan 05 '23 at 17:56
  • Does it have any impact on the results? If not, then it's allowed by the spec. – Barmar Jan 05 '23 at 17:59

1 Answers1

2

(V8 developer here.)

I'm pretty sure this is just an internal implementation detail (window is split into two objects under the hood, for complicated reasons) that the console.dir implementation isn't hiding correctly. Filed crbug.com/1405301.

Rest assured that the prototype chain that regular JavaScript code can observe is as it should be, with no unexpected copies of anything. You can easily check this with window.__proto__ === Window.prototype, which returns true as it should.

jmrk
  • 34,271
  • 7
  • 59
  • 74
  • Thank you. In case you know the answer, here is another question I just posted related to how browsers create the global window object: https://stackoverflow.com/questions/75026200/how-can-the-global-window-object-be-created-before-there-is-a-realm-in-existance – Magnus Jan 06 '23 at 02:17
  • Could you go into a bit of detail on those "complicated reasons", please? – Bergi Jan 06 '23 at 02:18
  • 2
    @Bergi: it's the actual global object and its proxy, which the spec calls `WindowProxy`. They appear as one object to JS code, but are actually two, and IIRC that becomes observable in certain situations around navigation. (I'm not an expert on that stuff, sorry.) V8 implements this as the real global object being the proxy's prototype, which makes many things "just work" but does require a bit of special-casing here and there. – jmrk Jan 06 '23 at 14:28
  • Thanks @jmrk. In case interested, we are debating an aspect of how the WindowProxy object works under the hood, here: https://stackoverflow.com/questions/75033793/what-is-the-purpose-of-passing-windowproxy-as-the-global-this-value/75039463#75039463 – Magnus Jan 07 '23 at 16:18