The enumerate trap and Object.create()
Brendan Eich
brendan at mozilla.org
Fri Jan 30 21:10:48 PST 2015
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,
/be
Allen Wirfs-Brock wrote:
> Thanks,
> Please file a bug on this at bug.ecmascript.org
>
> AllenOn Jan 30, 2015 8:41 PM, Leon Arnott<leonarnott at gmail.com> wrote:
>> 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.
>>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
More information about the es-discuss
mailing list