【问题标题】:What is in Object.__proto__?Object.__proto__ 中有什么?
【发布时间】:2017-04-16 16:44:04
【问题描述】:

在 Google Chrom 的 javascript 中,对象有一个名为 __proto__ 的属性,它指向它们的原型(或父)对象。

var foo = {};
console.log(foo.__proto__ === Object.prototype);    //returns true

但是,对于 Object 对象,这不正确

console.log(Object.__proto__ === Object.prototype);    //returns false

Object.__proto__ 属性似乎是一个空方法

> console.log(Object.__proto__.toString());
function () {}

除了作为关于依赖于标准机构之外的 javascript 功能的警告故事之外——Object.__proto__ 函数是什么?

【问题讨论】:

  • Object.__proto__ === Function.prototype ...对象是一个函数。 typeof Object === "function"
  • 您阅读过这份文件吗?它可能会澄清一些事情。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • ...和 ​​__proto__ 已添加到 ECMAScript 6。
  • ...Function.prototype 看起来是一个空函数的原因是内置构造函数的许多原型实际上是它们构造的对象的实例。例如,Array.isArray(Array.prototype); // true(或者可能不完全是一个实例,但它们与构造函数有某种关系。)
  • @squint, ...和Function.__proto__===Function.prototype

标签: javascript google-chrome prototype v8 proto


【解决方案1】:

形成对象图的顶部是为了与规范中其他地方设置的期望保持尽可能一致。

必然会出现无法使用正常对象链接的情况,因为您“用完了对象”。

对 JavaScript 的基本了解使我们期望 Object[[Prototype]] 是用于创建 Object 函数对象的函数的原型属性。

我们希望使用Function 函数对象创建Functions,所以...

Object.__proto__ === Function.prototype

因为我们位于对象图的顶部并希望保持预期行为的一致性,我们将Function[[Prototype]] 配置为Function.prototype

Function.__proto__ === Function.prototype

从而确保Function instanceof Function === true

我们可以证明Function.prototype 是一个特殊的函数对象,因为:

Function.prototype.prototype === undefined

...并且每个用户定义的函数(胖箭头除外)在其原型属性上都有一个对象。

由于以上原因:

Object.__proto__ === Function.__proto__

这可能看起来很奇怪,但如前所述,在对象图的顶部,我们有一组有限的候选对象可以指向。

TC-39 现在需要识别[[Prototype]]Object 中的[[Prototype]] 是什么。 根据上面我们知道Object[[Prototype]]Function.prototype

从某种意义上说,我们现在在对象图中高于Function.prototype,因此选择了一个特殊的Object 实例(“原型对象”)作为该值。

这意味着每个原型链的顶部都可以方便地与Object.prototype 绑定。

当然,这也满足了一切“都是对象”的理想要求。

Object.__proto__.__proto__ === Object.prototype 

此时我们需要完成对象图,所以我们将Object.prototype[[Prototype]]设置为null

Object.__proto__.__proto__.__proto__ === null

【讨论】:

  • 有用信息@BenAston——谢谢!但我不确定Object.__proto__ 信息是否正确? Object.__proto__.toString() 返回 "function () {}" - 即一个空函数,不是 [native code] 函数(Chrome,OS X El Cap)?回复:在标准机构之外,我的声明/snark 不清楚。我的理解是 proto 是在浏览器中实现的,尽管它不是 ES 标准的一部分,并且最近才被合并到 ES6 标准中。
  • Object.__proto__.toString() 的渲染将取决于您的浏览器版本。另外:你想让toString 打印出 C++ 源代码吗?如果你不相信我:告诉我是什么用户域函数创建了内置的Object 函数对象?
  • 我不确定您的描述是否 100% 准确的原因是,如果我在 Chrome 浏览器中使用本机代码记录一个函数(或使用 toString 方法),我会得到一些提及 [本机代码](function split() { [native code] }。但是,当 Chrome(或 .toString)渲染 Object.__proto__ 对象时,它不包含本机代码,看起来像一个空的用户空间函数(function() {}
  • 反对者,请解释!如果我错了,请解释我如何从错误中吸取教训。
  • 对有关“本机代码”功能的不正确信息投了反对票。现在已经取消了反对票。
【解决方案2】:

基于上面的squint's cmets,我已经能够深入了解这一点。我未说明的、不正确的(和 10 年以上)假设是全局 Object 辅助对象的原型对象也是 javascript 原型链顶部/末端的顶级“原型原型”。这不是真的。

Object 辅助对象和Function 辅助对象都具有相同的父原型对象

console.log( Object.__proto__ === Function.__proto__ );    //true

所以,Object.__proto__ 指向一个空函数的原因是——空函数它的 Object 对象的原型对象。如果您想从Object(不使用.prototype)获得原型的原型,则需要进一步挖掘。

console.log( Object.__proto__.__proto__ === Object.prototype );         //true

我还整理了一个快速图表,它描绘了一些 Javascript 的低级帮助器/构造器对象的真实原型。

最后——我还发现谷歌浏览器已经实现了Reflect对象which includes a getPrototypeOf method,它似乎与Object.getPrototypeOf方法相同。

【讨论】:

  • Re: down-voters -- 如果以上内容不正确,请告诉我。如果它是正确的,但你不喜欢我的观点——我想我会接受反对票;)
  • 我认为你是对的,但图表令人困惑,因为我希望箭头指向另一个方向(继承方向)。这句话令人困惑:“Object helper 对象与 Function helper 对象共享其原型。” 措辞含糊。我不知道您何时谈论构造函数,它们的.prototype 或它们继承的对象(可通过__proto__ 访问)。所以这可能是 DV 的部分原因。
  • getPrototypeOfReflect 对象的新对象,但它通过 Object.getPrototypeOf 已经存在了很长一段时间。至少我认为他们是一样的。还没有真正看太多Reflect。编辑:我在文档上看到它们确实是一样的。很好。
  • 将措辞更改为更清晰,并更新了图表以使箭头指向层次结构的顶部。此外,FWIW,大多数文档对 .prototype 属性和对象真正的“父对象原型”缺乏明确性,这首先导致了这个问题。再次感谢@squint 的帮助!
猜你喜欢
  • 1970-01-01
  • 2016-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
  • 2011-12-03
  • 2013-08-23
相关资源
最近更新 更多