48

我知道每个 JavaScript 对象都有一个名为[[Prototype]]. 一些实现允许通过调用的属性访问它,__proto__而另一些则不允许。这个属性周围的括号有什么特殊意义吗?

4

3 回答 3

56

它是对象的“内部属性”。从ECMAScript 8.6.2开始:

本规范使用各种内部属性来定义对象值的语义。这些内部属性不是 ECMAScript 语言的一部分。它们由本规范定义,纯粹是为了说明目的。ECMAScript 的实现必须表现得好像它以此处描述的方式生成和操作内部属性。内部属性的名称用双方括号 [[ ]] 括起来。

声明“这些内部属性不是 ECMAScript 语言的一部分”意味着内部属性不是可以在实际代码中使用的标识符——内部属性不能作为包含它们的对象的成员访问。但是,它们可以通过特定的函数或属性来访问(例如,一些浏览器非常友好地允许您设置和获取属性,而 ES5 规范允许[[Prototype]]通过__proto__进行只读访问Object.getPrototypeOf)。

在单括号上使用双括号可能是为了避免与实际括号表示法(即属性访问)发生任何可能的混淆。

于 2013-06-18T17:08:41.990 回答
10

JavaScript [[原型]]

双括号[[Prototype]]是一种将一个对象与另一个对象联系起来的内部链接。

创建函数时,会创建一个名为原型的属性对象并将其添加到函数的名称变量(我们称之为constructor)。此对象指向或具有指向本机 JavaScript 对象的内部私有链接)。

例子:

function Foo () {
    this.name = 'John Doe';
}

// Foo has an object 'property' called prototype 
// prototype was created automatically when we declared the function Foo.
// Now, we can assign properties to it without declaring the prototype object first.
Foo.prototype.myName = function () {
    return 'My name is ' + this.name;
}

现在,如果我们要Foo使用关键字创建一个新对象,我们基本上是创建(除其他外)一个新对象,该对象具有指向我们之前讨论过new的函数原型()的内部链接:Foo

var obj = new Foo();

obj.__proto__ === Foo.prototype      // true
obj.[[Prototype]] === Foo.prototype  // true

作为

obj.__proto__ === obj.[[Prototype]]  // true

由于[[Prototype]]是到该函数对象的私有链接,因此许多浏览器正在为我们提供公共链接。那就是__proto__(发音为dunder proto)。

__proto__实际上是一个属于本机 JavaScript 对象的getterthis函数,并返回绑定的内部私有原型链接(返回[[Prototype]]of obj):

obj.__proto__ === Foo.prototype // true

顺便说一句,从 开始ES5,我们可以使用getPrototypeOf获取内部私有链接的方法:

obj.__proto__ === Object.getPrototypeOf(obj) // true

注意:这个答案并不打算涵盖创建新对象或新构造函数的整个过程,而是为了帮助更好地理解它是什么 [[Prototype]]以及它是如何工作的。

于 2015-09-23T03:06:10.050 回答
9

它在括号中的原因是表示它是私有财产。括号本身从未在任何地方的代码中使用。

正如您所指出的,某些实现提供了对该私有属性的访问__proto__,但它是非标准的。

于 2013-06-18T17:05:35.380 回答