Java脚本中__proto__与[[Prototype]]的区别

2022-03-30 00:00:00 inheritance javascript prototype

我也读过并尝试理解其他类似这个问题的答案(like this one),但原型继承的概念对我来说仍然不是很清楚。现在最让我困惑的是,__proto__[[ Prototype ]]之间的实际区别是什么?据我所知,[[ Prototype ]]是一个将一个对象绑定到另一个对象的内部链接";。但当我在YouTube上看到一个教程时,它就变得模棱两可了,因为每当他们创建一个对象时,如果他们试图在他们的浏览器控制台中使用console.log记录它,那么它实际上有__proto__属性,但当我尝试做同样的事情时,它会输出[[ Prototype ]]。所以我想知道为什么会这样?什么是内部链接?提前感谢!:) 以下是在Firefox中以Chrome和";<;prototype>;";格式输出&[[Prototype]]&的代码。

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
function User(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

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

console.log(user);


解决方案

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

示例:

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

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

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

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

  • Object.setPrototypeOf()

  • Object.getPrototypeOf()


除了[[prototype]]之外,ECMAST规范中还提到了其他内部插槽,并且我们编写的Java脚本代码无法访问这些内部插槽。

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

What is an "internal slot" of an object in JavaScript?

相关文章