On Nov 13, 2012, at 12:52 PM, David Bruant wrote:
> Le 13/11/2012 21:25, Tom Van Cutsem a écrit :
>> 2012/11/13 Allen Wirfs-Brock <[email protected]>
>>
>> I think there is agreement that [[HasOwnProperty]] is just an optimization
>> of ToBoolean([[GetOwnPropertuy]]). Its only purpose is to avoid unnecessary
>> reification of property descriptors. If that optimization isn't important we
>> should just eliminate [[HasOwnProperty]].
>>
>> I understand your point that on normal objects, implementations are free to
>> avoid actually allocating a property descriptor for has or hasOwn checks. As
>> far as the spec is concerned, the derived traps are completely unnecessary:
>> we could hypothetically rewrite the entire spec to use only fundamental
>> traps, and implementors would be free to cut as many corners as they want
>> for non-proxy objects.
>>
>> When I mentioned that derived traps avoid unnecessary allocations, I was
>> really thinking about this from the point-of-view of the ES6 metaprogrammer.
>> Say I'm creating my own virtual object abstraction whose properties reside
>> in an external map, so I dutifully implement all the traps:
>>
>> var store = new Map()
>> var p = new Proxy( { } /* target doesn't matter */ , {
>> hasOwn: function(ignoreTarget, name) { return store.has(name); },
>> getOwnPropertyDescriptor: function(ignoreTarget, name) {
>> var e = store.get(name);
>> return e === undefined ? undefined : {value:e, ...};
>> },
>> ...
>> };
>>
>> Say we remove the "hasOwn()" trap, calling the getOwnPropertyDescriptor trap
>> instead. Now my virtual object abstraction does need to allocate a
>> descriptor.
> For the particular case you've written, when going for hasOwnProperty.call or
> the in operator, the JS engine knows it needs to output a boolean, so it can
> "rewrite" (or contextually compile) your trap last line as "e===undefined"
> (since "undefined" is falsy and objects created by object literals are
> truthy). In that particular case, the allocation isn't necessary provided
> some simple static analysis.
> Maybe type inference can be of some help to prevent this allocation in more
> dynamic/complicated cases too. I would really love to have implementors POV
> here.
>
If you can trace/inline across internal method calls and are smart enough in
your analysis you probably can eliminate the allocation. The internal method
calls come into play because you may have Proxies or other exotic objects on a
[[Prototype]] chain so things that involve proto climbing will bounce back and
force between internal methods and trap handlers.
My general philosophy has always been that when programming in an object-based
language, a programmer shouldn't be afraid of creating and using objects. It's
the implementation's job to make sure that perspective is justified. Given
everything else that is likely to be going on in a rich proxy, this particular
point may be unnecessary early optimization.
Regardless, my main concern isn't this optimization issue, but instead a
concern about it being too easy to inadvertently define an internally
inconsistent Proxy.
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss