__proto__
是Object.prototype
的属性:
Object.prototype.hasOwnProperty('__proto__'); // true
但是,getOwnPropertyNames在Firefox上忽略它:
Object.getOwnPropertyNames(Object.prototype).indexOf('__proto__'); // -1
适用于Chromium 43和IE 11,很难。
AFAIK,根据ECMAScript 5规范,getOwnPropertyNames应该列出它:
15.2.3.4 - Object.getOwnPropertyNames ( O )
调用 getOwnPropertyNames 函数时,如下所示 采取的步骤:
- 如果Type( O )不是Object,则抛出 TypeError 异常。
- 让数组成为创建新对象的结果,就好像表达式
new Array ()
一样Array
是标准内置 具有该名称的构造函数。- 让 n 为0。
- 对于 O 的每个已命名的自有属性 P
- 让 name 为字符串值,即 P 的名称。
- 使用参数ToString( n ),PropertyDescriptor {[[Value]]调用 array 的[[DefineOwnProperty]]内部方法: name ,[[Writable]]: true ,[[Enumerable]]: true ,[[Configurable]]: true < / strong>}和 false 。
- 将 n 增加1。
- 返回数组。
醇>
__proto__
是Object.prototype
的命名自有属性(否则,hasOwnProperty将返回false,因为[[GetOwnProperty]]将返回undefined)。因此,它应该由getOwnPropertyNames列出,不应该吗?
ECMAScript 6中应该有所不同吗? ES6草案确实改变了一些事情:
19.1.2.7 - Object.getOwnPropertyNames ( O )
调用 getOwnPropertyNames 函数时,如下所示 采取的步骤:
- 返回GetOwnPropertyKeys( O ,字符串)。
醇>19.1.2.8.1 - Runtime Semantics: GetOwnPropertyKeys ( O, Type )
使用参数 O 调用抽象操作GetOwnPropertyKeys 和类型其中 O 是一个对象而类型是ECMAScript之一 规范类型字符串或符号。采取以下步骤:
- 让 obj 成为ToObject( O )。
- ReturnIfAbrupt( OBJ )。
- 让键为 obj 。[OwnPropertyKeys]。
- ReturnIfAbrupt(键)。
- 让 nameList 成为新的空List。
- 以List顺序重复键的每个元素 nextKey ,
- 如果Type( nextKey )是 Type ,那么
- 将 nextKey 附加为 nameList 的最后一个元素。
- 返回CreateArrayFromList( nameList )。
醇>9.1.12 - [[OwnPropertyKeys]] ( )
当调用 O 的[[OwnPropertyKeys]]内部方法时 采取以下步骤:
- 让键成为新的空List。
- 对于作为整数索引的 O 的每个自己的property key P ,按升序数字索引顺序
- 添加 P 作为键的最后一个元素。
- 对于属于字符串但不是整数索引的 O 的每个自己的property key P ,在属性创建顺序中
- 添加 P 作为键的最后一个元素。
- 对于作为符号的 O 的每个自己的property key P ,在属性创建顺序中
- 添加 P 作为键的最后一个元素。
- 返回键。
醇>
[[OwnPropertyKeys]]应返回包含"__proto__"
的列表,GetOwnPropertyKeys应返回带"__proto__"
的数组,因为其类型应为String。
即使它是Symbol而不是String(这没有多大意义),getOwnPropertySymbols应该包含__proto__
,但它返回一个空数组。
因此,这是一个错误,还是规范的复杂性适用于此?
答案 0 :(得分:3)
是的,这似乎是一个错误。来自this bug report(观察到类似的奇怪现象):
我们在没有a的对象上过滤__proto__ [[Prototype]],因为我们不想将它暴露给网络。或 至少那是当时的意图,尤其是没有其他意图 浏览器在Object.prototype上公开了那个属性,并在那里 有机会杀死__proto__。我仍然有一些希望 __proto__可以被杀死,我自己;其他人不同意。
他们需要为ES6修复此问题。