Type of property names, as seen by proxy traps

Andreas Rossberg rossberg at google.com
Thu Jul 14 03:52:14 PDT 2011


Very much appreciated. Given all the nasty mutability in JS, I think
for the non-normative JS implementations you also might want to note
that it assumes that nobody has hampered with the primordial Object
object.

/Andreas


On 14 July 2011 12:34, Tom Van Cutsem <tomvc.be at gmail.com> wrote:
> Follow-up: I updated
> <http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics> with a
> more precise specification of the default behavior of all derived traps.
> This should also resolve the double-coercion issue with Object.keys.
> In summary:
> - for "has", "hasOwn" and "get" it's easy to fall back on specifications of
> existing built-ins (Object.[[HasProperty]] for "has",
> Object.prototype.hasOwnProperty for "hasOwn" and Object.[[Get]] for "get")
> - for "set", falling back on Object.[[Put]] is not ideal, as this built-in
> performs redundant invocations of [[Get{Own}Property]] through [[CanPut]].
> Starting from Object.[[Put]] and the default "set" trap as specified in JS
> itself, I formulated a new "DefaultPut" algorithm that avoids this
> redundancy.
> - for "keys" and "enumerate", there is no proper built-in to fall back on. I
> added two algorithms (FilterEnumerableOwn and FilterEnumerable) that take
> the uncoerced result of the get{Own}PropertyNames trap, and filter out the
> enumerable properties, specced after "Array.prototype.filter".
> I also updated
> <http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults> so
> that it is clear that that section is only a non-normative description of
> how derived traps could be implemented in pure Javascript.
> Cheers,
> Tom
>
> 2011/7/8 Tom Van Cutsem <tomvc.be at gmail.com>
>>
>> I believe the alternative that David is talking about is the following
>> (pending the acceptance of
>> <http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy>)
>> keys: function(proxy) {
>>   return Object.getOwnPropertyNames(proxy).filter(
>>       function (name) { return Object.getOwnPropertyDescriptor(proxy,
>> name).enumerable });
>> }
>> (assuming that Object here refers to the built-in Object)
>> With this definition, I don't see the need for double coercion: the
>> handler's "getOwnPropertyNames" trap is called, and its result is coerced.
>> Then, the proxy implementation "knows" that each of the above |name|s passed
>> to "getOwnPropertyDescriptor" will be a String already, so it doesn't need
>> to coerce again. Finally, `keys' does not need to coerce its own result
>> array, since it is simply a filtered version of an already fresh, coerced
>> array.
>> Perhaps all self-sends to fundamental traps should be expressed in terms
>> of the operation that causes the trap, rather than a direct trap invocation.
>> Similar issues could arise in the default 'set' trap behavior when it calls
>> 'this.defineProperty' rather than 'Object.defineProperty(proxy,...)'.
>> 2011/7/7 Andreas Rossberg <rossberg at google.com>
>>>
>>> On 7 July 2011 19:35, David Bruant <david.bruant at labri.fr> wrote:
>>> >> No, with the current keys default trap (calling
>>> >> this.getOwnPropertyNames()) there is no double conversion. Only one at
>>> >> the exit of the keys trap. There would be 2 conversions if the "keys"
>>> >> trap had the proxy argument (based on
>>> >>
>>> >> http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)
>>> >> and if internally, the default keys trap was calling
>>> >> "Object.getOwnPropertyNames(proxy)" (which would call the trap and do
>>> >> type coercion).
>>> >>
>>> >> But the current implementation and a type coercion only when going out
>>> >> of traps would do double-conversion.
>>> > "not". "would not do double-conversion", sorry.
>>>
>>> I thought the fix we were discussing was changing the `keys' default trap
>>> from
>>>
>>> keys: function() {
>>>  return this.getOwnPropertyNames().filter(
>>>    function (name) { return
>>> this.getOwnPropertyDescriptor(name).enumerable }.bind(this));
>>> }
>>>
>>> to something along the lines of
>>>
>>> keys: function() {
>>>  return this.getOwnPropertyNames().filter(
>>>    function (name) { return this.getOwnPropertyDescriptor('' +
>>> name).enumerable }.bind(this));
>>> }
>>>
>>> That would fix passing non-strings to the getOwnPropertyDescriptor
>>> trap, but introduce double conversions when you invoke Object.keys.
>>> I'm not sure what alternative you are proposing now.
>>>
>>> /Andreas
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>


More information about the es-discuss mailing list