编辑2012年2月:下面的答案不再准确。__proto__被作为“标准可选”添加到ECMAScript 6中,这意味着它不需要实施,但如果要实施,则必须遵循给定的规则集。目前尚无定论,但至少它将正式成为JavaScript规范的一部分。
这个问题比表面上看起来要复杂得多,而且就Java组件内部知识而言,这超出了大多数人的薪水等级。
在prototype
创建该对象的新的子对象时,对象的属性使用。更改它不会反映在对象本身中,而是在将该对象用作其他对象的构造函数时反映出来,并且在更改现有对象的原型时没有用。
function myFactory(){};
myFactory.prototype = someOtherObject;
var newChild = new myFactory;
newChild.__proto__ === myFactory.prototype === someOtherObject; //true
对象具有内部[[prototype]]属性,该属性指向当前原型。它的工作方式是:只要调用对象的属性,它将从该对象开始,然后遍历[[prototype]]链,直到在根Object原型之后找到匹配项或失败为止。这就是Javascript允许运行时构建和修改对象的方式。它有一个搜索所需内容的计划。
该__proto__
属性存在于某些实现中(现在有很多):任何Mozilla实现,我所知道的所有Webkit实现,其他一些实现。此属性指向内部[[prototype]]属性,并允许在对象创建后进行修改。由于这种链式查找,任何属性和功能都将立即切换以匹配原型。
此功能虽然现在已标准化,但仍不是JavaScript的必需部分,并且在支持该功能的语言中,很有可能会将您的代码归为“未优化”类别。JS引擎必须尽全力对代码进行分类,尤其是经常访问的“热”代码,如果您正在做诸如修改之类的事情__proto__
,它们将根本无法优化您的代码。
这篇文章https://bugzilla.mozilla.org/show_bug.cgi?id=607863专门讨论的当前实现__proto__
以及它们之间的区别。每个实现都有不同的实现方式,因为这是一个难题,尚未解决。Java语言中的所有内容都是可变的,除了a。)语法b。)宿主对象(DOM在技术上不在Javascript之外)和c。)__proto__
。其余的一切完全掌握在您和所有其他开发人员的手中,因此您可以看到为什么__proto__
伸出来就像拇指酸痛一样。
有一件事情是__proto__
可以做到的,而这在其他方面是不可能做到的:在运行时指定对象原型与其构造函数分开。这是一个重要的用例,也是__proto__
尚未死亡的主要原因之一。非常重要的一点是,这已经成为和声制定中的一个重要讨论点,或者即将被称为ECMAScript6。在创建过程中指定对象原型的能力将成为下一版Javascript的一部分,而这将是指示__proto__
日期的铃铛已正式编号。
在短期内,__proto__
如果您要针对支持它的浏览器(不支持IE,也永远不会支持IE)使用,则可以使用。由于ES6直到2013年才能最终定稿,因此它可能会在接下来的10年中在webkit和moz中使用。
Brendan Eich -re:ES5中新Object方法的方法:
抱歉,但是可设置__proto__
,除了对象初始化程序的用例之外(例如,在尚未到达的新对象上,类似于ES5的Object.create),这是一个可怕的想法。我写这是__proto__
在12年前设计并实现可设置的。
...缺乏分层是一个问题(考虑JSON数据和一个key "__proto__"
)。更糟糕的是,可变性意味着实现必须检查循环原型链,以避免循环。[需要不断检查无限递归]
最后,__proto__
在现有对象上进行更改可能会破坏新原型对象中的非泛型方法,而该方法可能无法在__proto__
正在设置其的接收器(直接)对象上运行。通常,这只是一种不良做法,是一种故意类型混淆的形式。