iterate and enumerate trap signature inconsistency

David Bruant bruant.d at
Wed Sep 12 01:27:50 PDT 2012

Le 12/09/2012 08:19, Tom Van Cutsem a écrit :
> 2012/9/11 Mark S. Miller <erights at <mailto:erights at>>
>     [...]
>     If we change this API from returning an array of strings to
>     returning an iterator, I agree that alters the balance and
>     justifies waiving this particular guarantee.
> I also don't see any real issues with waiving the duplicate names 
> check. It's unrelated to the usual 
> non-configurability/non-extensibility invariants.
> Just to spell it out, that would mean that in the following code:
> for (var name in obj) { ... }
> where obj is either a proxy or an object with a proxy in its prototype 
> chain, |name| can be bound to the same string multiple times through 
> the loop.
There are numerous examples where ES5 assumptions are questioned by 
proxies, like:

     for(var p in obj){
         var desc = Object.getOwnPropertyDescriptor(obj, p)
         // ...

In this snippet, ES5 semantics guarantees that desc will be an object at 
every iteration. Proxies challenge this assumption (because of the 
enumerate trap, but also the combination between the enumerate and 
getOwnPropertyDescriptor trap). But as Mark said, there is a trade-off 
to be found.

> Note that even if we would waive the duplicate property check, the 
> proxy still needs to return a wrapped iterator for the enumerate() 
> trap to:
> - coerce each produced value to a String
> - check whether all non-configurable enumerable properties of the 
> target have been produced. One way to check this would be to retrieve 
> these properties in a set before the start of the loop, and remove 
> each encountered property from the set. If, after the very last loop 
> iteration, the set is non-empty, the proxy throws a TypeError.
Sounds good and it doesn't sound like there is additional cost against 
the current design.
For the second check, I'd like to note a couple of implementation 
details which are relevant I think. First, as you suggest, the set of 
minimum reported properties has to be decided before the first iteration 
(otherwise, this set may change over the course of the loop). Second, an 
unanswered question is how this set is being retrieved. Is the JS 
runtime performing an Object.getOwnPropertyDescriptor on the proxy 
(calling the trap)? on the target directly? If the target is itself a 
proxy, on the target at the end of the chain (so that no intermediate 
trap is being called)?
Right now, I have no preference for any of these solutions, but it's a 
detail that will be visible from user script, so it needs to be decided 
for the sake of interoperability.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list