possible excessive proxy invariants for Object.keys/etc??

Allen Wirfs-Brock allen at wirfs-brock.com
Wed Nov 21 08:37:00 PST 2012

On Nov 21, 2012, at 1:55 AM, David Bruant wrote:

> Le 21/11/2012 01:06, Allen Wirfs-Brock a écrit :
>>>>> b) that all the elements of the result are Strings
>>>> And presumably Symbols.  We have to also accommodate Symbols, at least for getOwnPropetyNames.  Regardless, why is this important?  More below...
>>>> Same argument as above.
>>>> I recall there was some concern about symbols showing up in existing reflection methods like Object.getOwnPropertyNames. Not sure how that got resolved. It's basically touching upon the same issue of whether we can change the return type of existing methods.
>> I'm assuming we are excluding symbols from [[Enumerate]] and [[Keys]]
> Why so? I would assume unique symbols to show up for these.

I believe that the POR is that Symbol keys are never enumerated (even if associated with a the property attribute that has [[Enumerable]]: true).  I suppose a proxy could violate that invariant (I wouldn't want to actively enforce it) but would be a buggy proxy.

>> so it is only [[GetOwnPropertyNames]] that have this concern.
> and of course non-enumerable unique symbols for this operation.

ie, private Symbols

(private Symbols, not only are always non-enumerable.  They are never reflected by primitive operation unless the symbol value is explicitly presented as an argument.  You can getOwnPropertyDescriptor using a private symbol, but getOwnPropertyNames never includes them)

> For both case, I think returning unique symbols work as long as ES6 doesn't consider that objects have built-in unique-symboled properties (because that could probably break existing code).

I assume by unique-symbol you mean the samething as private symbol. The above will hold, assuming we make @@interator, @@toStringTag, @@hasInstance, etc. private symbols.  While they need to be well-known, I don't see any reason why they shouldn't also be private.

>> One way or another we have to be able to reflectively get a list of symbol keyed properties.
>> We can either:
>> 1) include them in the Object.getOwnPropertyNames result.
> 1bis) Make all built-in symbols (like @iterable) private
>> 2) Consider getOwnPropertyNames depreciated (it actually lives forever) and replace it with a new Object.getOwnPropertyKeys that includes non-private Symbol keys
>> 3) Keep getOwnPropertyNames as is and add Object.getOwnPropertySymbols that only returns the non-private-Symbol keys.
>> 1) has the greatest backward compat concerns, but is the simplest to provide and for ES programmers to deal with going forward.
> Since the use of Object.getOwnPropertyNames may not be widespread, maybe that making non-enumerable unique symbol properties could do the trick (as it has with new {Object, Array, etc.}.prototype additions)
> 1bis) If all standard built-in names are private, they're not enumerated, neither in for-in, Object.keys, Object.getOwnPropertyNames and you can have a unique name in any of these enumeration operation if you've added them manually, so, no backward compat (or close enough that it's acceptable in my opinion)
>> 2) Eliminates the compat risk but creates perpetual potential for a: used gOPNames when I should have used gOPK  hazard.
>> 3) Eliminates the compat risk but means everybody who wants to deal with all own properties have to deal with two lists of keys.  They also loose relative insertion order info relating key/symbol property keys.
> It's a bit unfortunate to make all built-in symbols private (because they ought to be unique), but it feels like something acceptable.
> It may induce a bit of boilerplate for proxy whitelists (because all built-in names like @iterable would need to be added), but a built-in constructor helper that would generate sets with all built-in names in it could solve that issue easily.

Good point about the white lists,  that changes my mind about making the built-in symbols private. I think I'd prefer to take the risks of alternative  1 rather than forcing proxy writers to deal with them in white lists.  I think there is probably a greater risk of people messing up whitelisting than that there will be campat. issues with gOPN.  Note that even in legacy code, if a gOPN symbol  valued element is used in any context that requires a property key, things will still work fine.  It is only explicitly doing string manipulation on a gOPN element that would cause trouble. For example, trying to string prefix every element a list of own property names.

My second choice would be adding getOwnPropertyKeys.  I would also only want to have a getOwnPropertyKeys internal method/trap and would defined getOwnPropertyNames as filtering that list.


> David
> [1] http://wiki.ecmascript.org/doku.php?id=strawman:enumeration

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121121/8d8d1b5c/attachment.html>

More information about the es-discuss mailing list