Yet more ambiguities in property enumeration

Allen Wirfs-Brock Allen.Wirfs-Brock at
Fri May 7 10:22:39 PDT 2010

While 12.6.4 is does not explicitly talk about this case I think it implicitly covers it.

Line 6.a (of the first algorithm, 7.a of the second) says "Let P be the name of the next property of obj whose [[Enumerable]] property is true".
I don't  believe that there is any other operation  or function in ES5 that when doing a property access by-passes a own property based upon some condition and instead accesses as shadowed inherited property.  Given that it's pretty clear that the quoted sentence should be read as if it said "Let P be the name of the next property accessible via the [[Get]] internal method of obj whose [[Enumerable]] property is true"

Also note that the final paragraph says "a property of a prototype is not enumerated if it is "shadowed" because some previous object in the prototype chain has a property with the same name".  Note this just says  "shadowed" which I believe (I probably wrote it :-) show be interpreted in the accessible via [[Get]] sense.  In particular, it does not say something like 'has the same name of a enumerated property of some previous object in the prototype chain"

Given these two points of the specification, I think it takes some pretty creative interpretation to arrive at the Webkit/V8 interpretation.  I suspect, that their behavior is probably an implementation artifact rather than something intentional.  I can enter the more explicit formulation of (6.a/7.a)  into the errata if there is a consensus that it is really needed, but I think we are also fine without it.


From: es-discuss-bounces at [mailto:es-discuss-bounces at] On Behalf Of Mark S. Miller
Sent: Friday, April 23, 2010 9:01 AM
To: es5-discuss at; es-discuss
Cc: Mike Stay
Subject: Yet more ambiguities in property enumeration

Mike Stay (cc'ed) noticed the following ambiguity:

What should the following print?

    var base = {x:8};
    function showProps(obj) {
      var result = [];
      for (var k in obj) {
        result.push(k, ': ', ''+obj[k], '\n');
      return result.join('');
    var derived = Object.create(base, {x: {value: 9, enumerable: false}});

Of current ES5 implementations in progress,

* TraceMonkey and SES5/3 (Mike Stay's emulation of the Secure subset of EcmaScript 5 strict on current ES3R browsers) currently gives
     the empty string,
  meaning that the non-enumerable "x" in derived shadows the enumerable "x" from base.

* WebKit nightly and V8 currently gives
    "x: 9"
  meaning that the enumerable "x" from base shows through, causing the above loop to look up the value of the unenumerable shadowing "x" property.

I have not tested any other partial ES5 implementations (Rhino, ObjectPascal, ??).

The relevant test seems to be ES5 section 12.6.4 step 6.a (and likewise 7.a for the next production):

      Let P be the name of the next property of obj whose [[Enumerable]] attribute is true.

More information about the es5-discuss mailing list