【问题标题】:What is the significance of the double brackets for the [[prototype]] property in JavaScript?JavaScript 中 [[prototype]] 属性的双括号有什么意义?
【发布时间】:2013-06-15 00:23:36
【问题描述】:

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

【问题讨论】:

  • 双括号通常表示一个模板。某些脚本可能将 [[Prototype]] 替换为原型库的路径?

标签: javascript prototype


【解决方案1】:

JavaScript [[Prototype]]

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

在创建函数时,会创建一个名为 prototype 的属性对象并将其添加到函数的名称变量(我们称之为constructor)。此对象指向原生 JavaScript 对象,或具有指向原生 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;
}

现在,如果我们使用 new 关键字从 Foo 创建一个新对象,我们基本上会创建(除其他外)一个新对象,该对象具有指向函数原型 (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__ 实际上是一个 getter 函数,属于本机 JavaScript 对象,并返回 this 绑定的内部私有原型链接(返回 [[Prototype]]obj):

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

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

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

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

【讨论】:

  • obj.[[Prototype]] === Foo.prototype 给出语法错误:Uncaught SyntaxError: Unexpected token [。您不能以成员身份访问内部属性。还要检查@apsillers 的答案。
  • @Wilt,正如标题所说,[[Prototype]] 是一个内部链接,不能直接访问(但它仍然存在)。浏览器给了我们 proto 并且 JS 给了我们 getPrototypeOf 来访问它。对不起,如果答案不够清楚。比较是为了证明一个概念。不要在浏览器控制台中运行。希望有意义
  • 我明白了。我只是想在其他人的评论中说明这一点。从您的示例看来,这一行可以在代码中执行;)
  • @liorElrom obj.[[Prototype]] === Foo.prototype 真的很混乱,为什么不改成obj.__proto__ === Foo.prototype。这仍然是准确的,对吗?
  • @SergeyPleshakov,我认为我选择使用[[Prototype]] 演示它的原因是问题在于试图弄清楚双括号是什么。但是,您是对的,在这种情况下它们是相同的。
【解决方案2】:

它是对象的“内部属性”。来自ECMAScript 8.6.2

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

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

在单括号上使用双括号可能是为了避免与实际的bracket notation 混淆(即属性访问)。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 为什么是双括号?一个支架就够了吗?不是吗?
    • @Geek - 单括号可能与数组表示法混淆。就像我说的,这些括号永远不会出现在代码中。
    猜你喜欢
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多