The enumerate trap and Object.create()

Leon Arnott leonarnott at gmail.com
Fri Jan 30 20:41:36 PST 2015


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:
```
  let obj = {"actual-property":1};

  let proxy = new Proxy(obj, {*enumerate(){
    yield "falsified-property";
  }});
```
The implication of the above is that all for-in loops run on the proxy will
always produce "falsified-property" and never "actual-property":
```
  for (i in proxy) {
    console.log(i); // Logs "falsified-property"
  }
```
However, this proxy behaviour can be easily bypassed by just adding
Object.create():
```
  for (i in Object.create(proxy)) {
    console.log(i); // Logs "actual-property"
  }
```
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
- "get", "set" and "has" - are specced to have their traps triggered by
operations performed on ordinary object inheritors of them.

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:
 * Is there a reason or requirement that enumerate traps only trigger when
for-in operations are performed on the proxy directly?
 * Could Ordinary Object [[Enumerate]] be changed to, at the least, require
prototypes' [[Enumerate]] be used to retrieve their properties, rather than
any method that would ignore it?

Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150131/b08c01ae/attachment.html>


More information about the es-discuss mailing list