首页 > 解决方案 > 我很难找到全局对象“窗口”的 __proto__

问题描述

我目前正在使用 Chrome。

console.log(window.__proto__.__proto__.__proto__);

console.log(window.__proto__.__proto__.__proto__ === EventTarget.prototype);

我发现上面的第一个代码返回 EventTarget.prototype

这可以通过第二个代码来验证,它返回“true”

此外,以下代码也返回 true:

console.log(EventTarget.prototype.__proto__ === Object.prototype);

但是,当您跟踪 EventTarget.prototype 的孩子是谁时,就会出现问题。

console.log(window.__proto__.__proto__);

上面的代码返回下面。

WindowProperties {Symbol(Symbol.toStringTag) : "WindowProperties" .....}

当我尝试跟踪构造函数“WindowProperties()”或对象“WindowProperties.prototype”时,

控制台说

未捕获的 ReferenceError:WindowProperties 未在 :1:13 定义

为什么会这样?

标签: javascriptgoogle-chromedomprototypeglobal-object

解决方案


因为没有内置的全局调用WindowsProperties暴露给您的代码。仅仅因为某些东西存在并且具有名称并不意味着您的代码可以访问它。例如:

const example = (() => {
    return new class Something { };
})();
console.log(example.__proto__.constructor.name); // Something
console.log(Something); // ReferenceError: Something is not defined

注意:我__proto__在上面的代码中使用过,因此它会与您的代码非常相似,但我建议不要__proto__在实际代码中使用。使用Object.getPrototypeOf(and,如果不可避免,Object.setPrototypeOf) 代替。__proto__是仅在浏览器中定义的已弃用功能,并非所有对象都具有它(尽管几乎所有对象都具有;它由 定义Object.prototype)。


旁注:你的代码让我对windowChrome 的血统感兴趣,所以我写了以下内容。你可能会觉得很有趣:

const seenBefore = new Set();
let indent = "";
let obj = window;
while (obj) {
    const proto = Object.getPrototypeOf(obj);
    if (seenBefore.has(proto)) { // Paranoia
        console.log("Got something we've seen before; breaking the loop");
        break;
    }
    seenBefore.add(proto);
    console.log(`${indent}${proto?.constructor?.name}`);
    indent += "  ";
    obj = proto;
}

在给我的 Chrome 上:

窗户
  窗口属性
    事件目标
      目的
        不明确的

在 Firefox 上,这给了我一些不同的东西:

窗户
  事件目标
    事件目标
      目的
        不明确的

推荐阅读