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?
(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 theconsole.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 returnstrue
as it should.