Le 12/11/2012 19:17, Allen Wirfs-Brock a écrit :
On Nov 12, 2012, at 2:21 AM, Brandon Benvie wrote:
Shouldn't it be the reverse, based on the removal of
getPropertyDescriptor/Names? The proxy controls what i's [[Prototype]] is which
indirectly directs how non-own lookups proceed. The functionality of `has` can
(and usually should) be derived from proto-walking hasOwn until true or null.
yes, that would be a good fix for this particular problem. [[HasOwnProperty]]
could remain as an internal method and HasProperty could be defined as an
abstraction operation that uses the [[Prototype]] internal accessor and
[[HasOwnProperty]].
Indeed. Otherwise, what happens with
Object.prototype.hasOwnProperty.call(new Proxy({}, handler), 'a') would
be unclear.
Another potential consistency issue is between [[HasOwnProperty]] and
[[GetOwnProperty]]. That could be eliminated by combining them into one
operation:
[[GetOwnPropety]](name, descriptorNeeded) -> descriptor | boolean | undefined
If descriptorNeeded is true it acts as the current [[GetOwnProperty]]. If
descriptorNeeded is false it acts as the current [[HasOwnProperty]].
At the handler-level it makes it impossible to override "hasOwn"without also overriding
"getOwnPropertyDescriptor"
The boolean isn't needed. It's possible to get rid of the
[[hasOwnProperty]] internal method and only keep [[GetOwnPropety]](name).
* "Object.prototype.hasOwnProperty.call(o, name)" would be defined as
ToBoolean(o.[[GetOwnProperty]](name))
* "name in o" would be the same thing with proto-climbing
Both hasOwnProperty.call and the in operator would call only the
getOwnPropertyDescriptor trap, the rest would be left to implementors.
It may be weird to get rid of both hasOwn and has traps and that
hasOwnProperty.call and the in operator call the
getOwnPropertyDescriptor trap, but it's the cost of wanting consistency
between [[GetOwnProperty]] and [[HasOwnProperty]]. I'm personally fine
with this; I have no preference for one side or the other.
From the spec point of view, it's possible to remove [[HasOwnProperty]]
as an internal method, but to define a helper function. The idea behind
doing this (apparently cosmetic) change could be to reach 1-to-1
correspondence between object internals and proxy traps.
I'd like to point out that long discussions have already occurred about
invariants and trap results consistency. By essence of allowing to
provide functions for handler traps, it's possible to allow arbitrary
inconsistencies. For instance:
// "temporal inconsistency"
var a = new WeirdObject();
console.log('yo' in a); // true
console.log('yo' in a); // false
console.log('yo' in a); // false
console.log('yo' in a); // true
// "get/set" inconsistency
var b = new WeirdObject();
b.yo = 26;
console.log(b.yo); // logs "what's up es-discuss!!"
These are other inconsistencies with the expectations we currently have
from objects. I can't help wondering why this inconsistency (or any
other inconsistency) would be considered more or less important than the
one discussed in this thread.
IIRC, previous discussions led to the conclusion that it's impossible to
get rid of all inconsistencies. The minimum consistency required was
defined for security purposes and led to the invariant enforcement checks.
I'm fine if we're discussing removing some other inconsistencies, but
I'd be more interested in seeing a principled way to decide which
inconsistency we're getting rid of and which we still allow. In other
word, what makes an given inconsistency a bad thing?
The previous answer we had was in essence "if it prevents defensive
programming" (Tom or Mark will correct me if I'm misinterpreting or
miswording it) and with the current proxy design, it's possible to offer
freedom to proxies as long as it's within the boundaries of respecting
non-configurable properties and non-extensible invariants.
What would be the new answer to my question?
David
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss