The enumerate trap and Object.create()
Thanks, Please file a bug on this at bug.ecmascript.org
Good catch! I think this old decision pre-dates for-of. Cc'ing Tom.
Leon, could you please cite the bug in a followup here if you file it? Thanks,
Seems a serious problem, but could be easily fixed (I think).
For Example, this could be used as [[Enumerate]] for ordinary objects:
9.1.11 [Enumerate]
When the [[Enumerate]] internal method of O and optional argument visitedSet is called the following steps are taken
Return an Iterator object, whose next method conforms to the following steps.
If visitedSet does not exist, let visitedSet be an empty set
Let allKeys be a list that contain of all property names of O
For each property key in allKeys
If visitedSet does not contains key and key is an enumerable property of O
Add key to visitedSet
Yield key
Let proto be the result of calling [[GetPrototypeOf]] internal method of O
Let protoIterator be the result of calling [[Enumerate]] internal method of proto
Yield* protoIterator
The bug has been filed: ecmascript#3724 Thanks.
Lately I've been puzzled about what the Proxy "enumerate" trap is supposed to accomplish w/r/t enumeration over prototype properties. Consider the following:
The implication of the above is that all for-in loops run on the proxy will always produce "falsified-property" and never "actual-property":
However, this proxy behaviour can be easily bypassed by just adding Object.create():
When for-in is performed on an inheritor of a proxy, the proxy's "enumerate" trap is never hit at all. This seems undesirable - I think it's intuitive that since enumeration is a prototype-traversing operation, it should also respect prototypes' traps. And, of course, that adding an empty ordinary object to the head of the prototype chain shouldn't dramatically alter the results of a for-in performed on that chain.
As far as I know, this enumerate trap prototype behaviour is unique among traps: the other three traps that explicitly deal with prototype properties
The reason for this is, of course, due to how Ordinary Object [[Enumerate]] is currently specced, compared to Ordinary Object [[Get]], [[Set]] and [[Has]]. [[Enumerate]] is required to process properties from prototypes of the object, but is not required to call the prototype's [[Enumerate]] as the means of accessing them. (In fact, the informative algorithm provided calls the prototype's [[OwnPropertyKeys]] instead.)
That being said, I want to ask:
Thanks.