[[Enumerate]] in the presence of prototype changes and property deletions.

# Gareth Smith (12 years ago)

This is my first post here - please let me know if I do something wrong!

I've filed an issue here: ecmascript#1444

Section 8.3.12 of the current draft[1] defines the behaviour of [[Enumerate]], and describes what should happen if properties are added or removed during enumeration:

"If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are not guaranteed to be visited in the active enumeration."

It is not so clear on what happens if we enter the loop with an enumerable property shadowing a non-enumerable one, and then delete the enumerable one before it is visited.

Perhaps the "nicest" reading of the existing text would be to treat the revealed properties the same way we would treat "added" properties. So, in this case, the "revealed" property would be checked for enumerability and skipped. This doesn't seem to be the only possible reading of the spec however. For example, while spidermonkey seems to behave as I had expected, V8 disagrees, and visits the non-enumerable property.

Essentially the same trick can be played by mutating proto during enumeration.

Here is a code snippit which demonstrates this behaviour, assuming that x happens to come before z in the enumeration order:

var a = {}; Object.defineProperty(a, 'z', {value: 'secret', enumerable: false}); var b = {x:0, z:"tricky", proto:a}; var ret = "We have not visited a.z"; var deleted_z_yet = false; for (var i in b) { if(i=='x') { delete b.z ; deleted_z_yet = true; } if (i=='z' && deleted_z_yet) { ret = "we have visited a.z" ; } }

A related issue is that the "informative algorithm" in this section seems to return a static list, which can't react to deleted properties. I've filed that issue here: ecmascript#1443

Finally, FWIW, when I filed these issues, I got a long wait (5 mins or so), followed by "internal server error" each time. However, when I tried to re-submit, I got a faster response informing me that my previous submission had succeeded. I don't know who to tell about this, and the "Help" link at the top of the bugzilla page 404s, so I thought I'd mention it here.

Thanks,

Gareth.

[1] people.mozilla.org/~jorendorff/es6-draft.html#sec-8.3.12 if you're reading the HTML version.