On Dec 2, 2012, at 8:44 AM, Tom Van Cutsem wrote:

> 2012/12/1 Allen Wirfs-Brock <[email protected]>
> Requirements:
> 1) In ES6 property keys are no longer limited to string values, we now also 
> have keys that are Symbols.
> 2) Some meta-programming tasks will requires a way to reflectively obtain a 
> list of all public property keys.
> 3) The existing reflection APIs for property keys (Object.getOwnPropertyNames 
> and Object.keys) only return string values and we don't want to break 
> existing clients of those functions by returning non-string values.
> 
> Solution:
> 1) Object.getOwnPropertyNames and Object.keys remain unchanged.  They only 
> return a string property key values.
> 2) Reflect.ownKeys(obj) is a new reflection function that returns an 
> iterator.  The iterator produces the keys of all public own properties of the 
> object pass as an argument.  This includes both string and Symbol key values. 
>  A property whose key is a private Symbol is not a public property and its 
> key is not returned by the ownKeys iterator.
> 3) The [[OwnPropertyKeys]] internal method is defined to return an iterator 
> with the same definition as used for Reflect.ownKeys.  (Reflect.ownKeys is 
> implemented as a call to this internal method).  [[OwnPropertyKeys]] replaces 
> the like-named internal method in the current spec. draft and also replaces 
> the [[GetOwnPropertyNames]] internal method used in the wiki Proxy proposals.
> 4) ownKeys is the corresponding Proxy trap. The getOwnPropertyNames trap is 
> removed.
> 5) Object.keys and Object.getOwnPropertyNames are respecified in terms of 
> [[OwnPropertyKeys]].  They internally drain the iterator and continue to 
> return arrays of strings.
> 
> Any objections?
> 
> Sounds good.
> 
> We probably still need to clear up the discussion on invariants for 
> [[OwnPropertyKeys]] on a non-extensible proxy. I don't remember if we reached 
> a consensus on that.

No, and I didn't address it in my proposal above.

I still think making [[OwnPropertyKeys]] produce an iterator makes sense.  But 
it probably means we have to change how we think about the its invariants as we 
can't necessarily check all of the values such an iterator may yield before 
returning it from the Proxy implementation of [[OwnPropertyKeys]].  We can 
however have that [[OwnPropertyKeys]] wrap the iterator returned by the ownKeys 
trap with another iterator that does an invariant check of the individual 
values returned by the trap provided iterator.

The first issue, with that approach, is whether such delayed invariant checking 
is acceptable. For example, returning a key that doesn't exist in a frozen 
target would throw on the iterator.next call that would return that key rather 
than when calling Object.getOwnPropertyKeys.  (However, 
Object.getOwnProperyNames/keys would still appear to throw immediately, because 
they drain the iterator).  This delayed checking seems ok to me, but you 
probably need to think about it from the perspective of membranes and similar 
Proxy use cases.

One difference with a deferred invariant check is that is to obtain a own 
property keys iterator before a Proxy object/target is frozen but not check its 
values until after it is frozen.  In this case, the keys produced by the 
iterator would not necessarily meet the target own property invariants of a 
frozen object.  However, I don't see that is significantly different from the 
current array valued calls which also can produce key values that may no longer 
be valid after the objet is frozen.

Deferred checking can easily enforce that a "new property key" isn't return 
returned (from the iterator) for a frozen object. It can also determine that 
all own property keys are returned for a frozen object (immediately before 
throwing IterationComplete check if the number of keys already yielded equals 
the number of own properties of the target, if not throw to indicate the 
invariant violation).

What isn't so easily do is make sure that for non-frozen objects all 
non-configurable property keys are returned. To do this would probably require 
accumulating every yielded key and then checking that list against the actual 
target properties immediately before StopIteration.

This makes be think that this final invariant perhaps isn't so important, even 
for the present non-iterator based definition of getOwnPropetyNames.  
Basically for non-frozen/sealed objects any point in time list of property keys 
may become stale before it is used. It may include keys that are no longer used 
and may miss keys that are now used.  Any inclusion decisions based upon the 
configurability of individual properties may no longer be valid. 

We've talked before about the need of a reliable property list for "deep 
freezing" objects.  In seems for situations like that you would want to 
separately determine if the object is sealed/frozen before calling 
Reflect.ownKeys.  If it is frozen/sealed, you can depend upon the results.  If 
not, that final invariant (and probably the others) doesn't really guarantee 
much. 

allen



_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to