为什么 "window" 对象有这么多嵌套的 "window" 对象?

Why does the "window" object have so many nested "window" objects?

例如,您可以使用 window 对象调用 alert 函数:

window.alert("Hello World!");

您还可以在 window 对象中使用 window 对象:

window.window.alert("Hello World!");

哎呀,你甚至可以这样做:

window.window.window.window.window.window.window.window.window.window.window.window.window.alert("Hello World!");

我知道这很荒谬,在现实生活中没有理智的开发人员会这样做,但为什么这可能呢?

为什么有这么多嵌套的 window 对象?

每个全局变量都是全局对象的属性。 window 是全局的,因此 window.window 必须存在并引用自身:

console.log(window.window === window)

but why is this possible?

这只是一个循环引用。 属性 的值是对象本身。简单示例:

var foo = {
  bar: 42
};
foo.foo = foo;
console.log(foo.bar);
console.log(foo.foo.bar);
console.log(foo.foo.foo.bar);

您在 DOM 中也有循环引用:

var body = document.body;
console.log(body.parentNode.children[1] === body);

它们不是嵌套对象 - 它们只是完全相同的对象。它(有点)是 属性 本身(因为所有全局对象都是 window 对象的属性,而 window 是全局的...):

var myGlobal = "Hello!";
console.log(window.myGlobal == window.window.myGlobal);
console.log(window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.window.myGlobal == myGlobal);

之所以称为 cyclic,是因为它是无限嵌套的 - 本质上是这样的:

window = {
    //All the globals and other stuff
    window: {
        //All the globals and other stuff
        window: {
            //All the globals and other stuff
            //...
        }
    }
};

The point of having the window property refer to the object itself, was likely to make it easy to refer to the global object. Otherwise, you'd have to do a manual var window = this; assignment at the top of your script.

如此处所述:window.window

Window 对象的 window 属性 指向 window 对象本身。因此,以下表达式都是 return 相同的 window 对象:

window.window
window.window.window
window.window.window.window
// ...

创建您自己的嵌套对象:

myObject = {}
myObject.myObject = myObject