gpt4 book ai didi

javascript - 为什么Object.prototype的__proto__是另一个Object.prototype?

转载 作者:行者123 更新时间:2023-12-05 03:25:39 25 4
gpt4 key购买 nike

如果我们在 chrome 控制台中创建一个数组,

arr=[1,2];

并使用 arr.__proto__.__proto__ 检查 chrome devtools 中的原型(prototype)链,我们得到以下结果。 enter image description here

如您所见,__proto__ 对象指向 null,这符合我的逻辑预期。但是当我尝试访问原型(prototype)链的同一级别时,即 Object.Prototype,通过使用 arr.__proto__,然后搜索下拉菜单,我得到了以下结果。 enter image description here

正如您在突出显示的行中看到的,这次 __proto__ 指向另一个 Object.Prototype。进一步打开它时,我得到了与上一个命令中相同的内容(检查上一张图片)。

谁能告诉我 Object.prototype 的这个额外层是如何在某些命令中创建的,而在其他命令中却没有?

附言我只是在学习原型(prototype)继承,这是我试图了解它是如何在 JS 环境中实现的。

最佳答案

这是由于 Chrome 开发工具中的一个奇怪行为。 (现已弃用)__proto__ 属性是一个 getter/accessor 属性,这意味着当它被访问时,它会运行一部分代码。这部分代码看起来像这样:

Object.getPrototypeOf(this); // which returns this[[Prototype]]

上例中的 this 通常是您调用 .__proto__ 的对象。例如,如果你做了 arr.__proto__,那么 this 就是 arr,所以我们最终得到了 arr 的原型(prototype) 预期的数组。在 Chrome 开发工具控制台中,情况有些不同。 getter 不是在 arr 这样的对象上调用,而是在您按下 (...) 时手动调用:

Image showing how an ellipsis icon can be pressed for the proto getter property

所以现在的问题是 - 在 __proto__ getter 中执行 Object.getPrototypeOf(this);this 的值是多少当在 Chrome 开发工具中手动调用它而不是通过 arr.__proto__ 等属性访问调用它时?这由 Chrome 开发工具团队决定,但它的行为方式似乎是将 this 设置为最初记录的对象 1。在您的第二个示例中,该对象是 arr.__proto__。结果,getter 最终再次显示 arr.__proto__ 的原型(prototype),而不是 null

下面的代码片段(请参阅 Chrome 控制台输出)是此行为的一个简单示例:

const obj = Object.create({
get nested() {
console.log("obj === this:", this === obj); // true
console.log("obj[[Prototype]] === this:", this === Object.getPrototypeOf(obj)); // false
return this;
}
}, {
foo: {
value: 'bar',
enumerable: true
}
});

// View chrome console for output
console.log(obj);

在上面的示例中,创建了一个具有属性 {foo: "bar"} 的新对象,该对象的原型(prototype)设置为具有名为 nested() {} 的 getter 的对象。此 getter 返回并记录 this 的值。当上面的代码在 Chrome 中运行时,通过单击 obj[[Prototype]] 上的 (...) 调用 getter(即:obj. __proto__) nested 属性,你会得到以下输出:

image to show that the nested getter logs the original object

上面两个红框代表同一个对象,说明getter里面的this没有引用原型(prototype)对象(即:{nested: (...)}) 当使用 (...) 调用时,而是引用最初记录的对象。与此不同,当您使用 arr.__proto__.__proto__ 时,记录的对象是 Object.prototype,因此当您调用 __proto__ getter 时, this 引用对象Object.prototype,当其原型(prototype)被访问时返回null

要正确遍历原型(prototype)链,您可以使用对 Object.getPrototypeOf() 的嵌套调用:

Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(arr))); // null

1 这只是基于一些观察的假设,但可能不正确 - 我不完全确定 chrome 如何决定将 this 设置为什么,但需要注意的重要一点是,getter 属性并不总是出现在直接对象中。

关于javascript - 为什么Object.prototype的__proto__是另一个Object.prototype?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71934960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com