__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异常。
  令array为创建新对象的结果,就像通过表达式new Array ()一样,其中Array是标准内置对象
  该名称的构造函数。
  令n为0。
  对于每个命名的自己的财产P of O
  
  令name为String值,即P的名称。
  使用参数ToString(n),PropertyDescriptor {[[Value]]调用数组的[[DefineOwnProperty]]内部方法。
  名称,[[可写]]:是,[[可枚举]]:是,[[可配置]]:是}和否。
  n递增1。
  
  返回数组。
  


__proto__Object.prototype的命名自有属性(否则,hasOwnProperty将返回false,因为[[GetOwnProperty]]将返回undefined)。因此,它应该由getOwnPropertyNames列出,不是吗?

ECMAScript 6是否应该有所不同? ES6草案确实更改了一些内容:


  19.1.2.7 - Object.getOwnPropertyNames ( O )
  
  调用getOwnPropertyNames函数时,以下内容
  采取的步骤:
  
  
  返回GetOwnPropertyKeys(O,String)。
  
  
  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添加为键的最后一个元素。
  
  对于每个自己的property key P of O(按字符串创建,但不是整数索引),按属性创建顺序
  
  将P添加为键的最后一个元素。
  
  对于每个作为符号的O的property key P,按属性创建顺序
  
  将P添加为键的最后一个元素。
  
  返回键。
  


[[OwnPropertyKeys]]应该返回一个包含"__proto__"的列表,而GetOwnPropertyKeys应该返回一个带有"__proto__"的数组,因为它的类型应该是String。

即使是Symbol而不是String(这没有什么意义),getOwnPropertySymbols也应包含__proto__,但它会返回一个空数组。

因此,这是一个错误还是规范的错综复杂?

最佳答案

是的,这似乎是一个错误。从this bug report(观察到类似的奇怪之处):


  我们从对象的属性中过滤出__proto__,而没有
  [[Prototype]],因为我们不想将其公开。或
  至少那是当时的意图,尤其是因为没有其他
  浏览器以这种方式公开了Object.prototype的属性,
  是杀死__proto__的机会。我仍然有希望
  我自己可以杀死__proto__;其他人不同意。


他们将需要针对ES6修复此问题。

关于javascript - getOwnPropertyNames在Firefox上忽略__proto__,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29104906/

10-11 05:16