1

__proto__ is a property of Object.prototype:

Object.prototype.hasOwnProperty('__proto__'); // true

However, getOwnPropertyNames ignores it on Firefox:

Object.getOwnPropertyNames(Object.prototype).indexOf('__proto__'); // -1

It works on Chromium 43 and IE 11, tough.

AFAIK, according to ECMAScript 5 spec, getOwnPropertyNames should list it:

15.2.3.4 - Object.getOwnPropertyNames ( O )

When the getOwnPropertyNames function is called, the following steps are taken:

  1. If Type(O) is not Object throw a TypeError exception.
  2. Let array be the result of creating a new object as if by the expression new Array () where Array is the standard built-in constructor with that name.
  3. Let n be 0.
  4. For each named own property P of O
    1. Let name be the String value that is the name of P.
    2. Call the [[DefineOwnProperty]] internal method of array with arguments ToString(n), the PropertyDescriptor {[[Value]]: name, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    3. Increment n by 1.
  5. Return array.

__proto__ is a named own property of Object.prototype (otherwise, hasOwnProperty would return false because [[GetOwnProperty]] would return undefined). Therefore, it should be listed by getOwnPropertyNames, shouldn't it?

Should that be different in ECMAScript 6? The ES6 draft changes a few things indeed:

19.1.2.7 - Object.getOwnPropertyNames ( O )

When the getOwnPropertyNames function is called, the following steps are taken:

  1. Return GetOwnPropertyKeys(O, String).

19.1.2.8.1 - Runtime Semantics: GetOwnPropertyKeys ( O, Type )

The abstract operation GetOwnPropertyKeys is called with arguments O and Type where O is an Object and Type is one of the ECMAScript specification types String or Symbol. The following steps are taken:

  1. Let obj be ToObject(O).
  2. ReturnIfAbrupt(obj).
  3. Let keys be obj.[OwnPropertyKeys].
  4. ReturnIfAbrupt(keys).
  5. Let nameList be a new empty List.
  6. Repeat for each element nextKey of keys in List order,
    1. If Type(nextKey) is Type, then
      1. Append nextKey as the last element of nameList.
  7. Return CreateArrayFromList(nameList).

9.1.12 - [[OwnPropertyKeys]] ( )

When the [[OwnPropertyKeys]] internal method of O is called the following steps are taken:

  1. Let keys be a new empty List.
  2. For each own property key P of O that is an integer index, in ascending numeric index order
    1. Add P as the last element of keys.
  3. For each own property key P of O that is a String but is not an integer index, in property creation order
    1. Add P as the last element of keys.
  4. For each own property key P of O that is a Symbol, in property creation order
    1. Add P as the last element of keys.
  5. Return keys.

[[OwnPropertyKeys]] should return a list which contains "__proto__", and GetOwnPropertyKeys should return an array with "__proto__", because its type should be String.

And even in case it was Symbol instead of String (which doesn't make much sense), getOwnPropertySymbols should include __proto__, but it returns an empty array.

Therefore, is it a bug, or what intricacy of the spec applies here?

Oriol
  • 274,082
  • 63
  • 437
  • 513

1 Answers1

3

Yes, this seems to be a bug. From this bug report (where similar oddities are observed):

We filter __proto__ out of properties on objects without a [[Prototype]], because we don't want to expose it to the web. Or at least that was the intent at the time, especially since no other browser exposed the property on Object.prototype that way, and there was a chance at killing __proto__. I still have some hope that __proto__ can be killed, myself; others disagree.

They will need to fix this for ES6.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375