__proto__ 和 [[ Prototype ]] 在 javascript 中的区别

Difference between __proto__ and [[ Prototype ]] in javascript

我已经阅读并尝试理解与此问题类似的其他答案(like this one),但原型继承的概念对我来说仍然不是很清楚。现在最让我困惑的是,__proto__[[ Prototype ]] 之间的实际区别是什么?据我所知,[[ Prototype ]] 是一个“内部link年龄,它将一个对象与另一个对象联系起来”。但是当我在 youtube 上看到一个教程时它变得模棱两可,因为每当他们创建一个对象并且如果他们尝试在浏览器的控制台中使用 console.log 记录它那么它实际上有 __proto__ 属性在其中,但是当我尝试执行相同操作时,它会输出 [[ Prototype ]] 。所以我想知道为什么会这样?什么是“内部link”?提前致谢! :) 下面是在 chrome 中输出 "[[ Prototype ]]" 和在 firefox 中输出 "" 的代码。

function User(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

const user = new User("Someone", "Something");

console.log(user);

双方括号表示法来自 ECMAScript 规范,它总是指代一个 内部 实体(字段、属性、插槽...),但它不是您的表示法可以在 JavaScript 代码中使用。它是语言实现者的信息,有助于精确定义语言的行为。

在控制台中,您可能会看到用这些双括号表示的信息,与 Chrome 控制台中的情况一样。 Firefox 使用不同的表示法:<prototype>.

现在进入你问题的核心。对象与其原型对象之间的 link 是该对象的 not an own JavaScript 属性 .这是一个 internal slot:

Internal slots correspond to internal state that is associated with objects and used by various ECMAScript specification algorithms. Internal slots are not object properties and they are not inherited.

你可以通过.__proto__获取原型对象,但是__proto__属性是一个getteron the Object.prototype object。所以这就像圈子里的 运行:当你写 obj.__proto__ 时,引擎需要知道原型链是什么,然后才能为你找到 __proto__ 值,因为它需要得到它通过继承——它本身不是 obj 的 属性。并找到继承 link 引擎将使用内部“槽” [[Prototype]].

每个对象的原型都保存在名为[[prototype]]内部插槽中,而__proto__只是一个getter/setter,定义在Object.prototype 对象,获取任何对象的 [[prototype]] 内部插槽的值。

示例:

const arr = [];

数组的每个实例都以 Array.prototype 作为其原型。因此,在上面的 arr 声明中,[[prototype]] 内部槽包含对 Array.prototype 的引用,并且在以下表达式中:

arr.__proto__ === Array.prototype  // true

arr.__proto__ 从内部 [[prototype]] 插槽获取 Array.prototype 对象。

如上所述,__proto__ 只是一个 getter/setter,它获取 [[prototype]] 内部插槽的值,并且仅出于兼容性原因才存在。它不应该在现代 javascript 代码中使用;以下两种方法应该用于 set/get 任何对象的原型:


除了 [[prototype]] 之外,还有其他内部插槽在 Ecmascript 规范中提到,我们编写的 javascript 代码无法访问这些内部插槽。

如果您需要了解有关内部插槽的更多信息,请阅读: