Le 10/01/2013 17:22, Nathan Wall a écrit :
Choosing symbols or a weakmap would make a huge difference in how proxy
replacement would react to DOM algorithms.
If the DOM in terms of accessing private properties, then proxies can
replace DOM objects transparently. Their "unknownPrivateSymbol" trap
will be called [2] and if they don't throw, the access to the private
property will be transparently forwarded to the target without the
private symbol ever leaking (it actually wouldn't need to exist in
implementations).
Private Symbols are great for their syntactic advantages, but they're also more
observable than WeakMaps, and can't be used as a replacement to closures for
representing internal state. As a library author, I find this unhelpful.
Consider the following SimpleDate implementations:
(code)
AFAIK the two ES6 implementations above should function the same, except when
(1) a Proxy uses a SimpleDate as the target and (2) a SimpleDate is frozen.
In the case of (1), the implementation using a private symbol will have
internal accesses to the `timestamp` symbol exposed through the
unknownPrivateSymbol trap.
The trap does not expose the symbol. That would be a bad leak.
The third "whitelist" argument in the proxy constructor is here to
communicate whether the proxy knows the privatesymbol or not.
When [[Get]] or [[Set]] (or other property operations) happens with a
whitelisted private symbol, the get or set (or other) trap is called
with the symbol itself (since it's known). If the name isn't in the
whitelist, the unknownPrivateSymbol trap is called with target as the
*only* trap argument (the private name is not exposed and that's on
purpose!)
In the case of (2), the implementation using a private symbol will fail on a
call to `setTime` when the object is frozen (I think).
True. Note that it's not a new thing. It's also an issue with string
properties. In that regard, symbols are only consistent with what
currently exists.
It sounds to me like if I am writing defensive library code, I will always want
to use a WeakMap instead of a Symbol.
You can also wrap all the objects you expose in a proxy that doesn't
allow being frozen (throw in the preventExtensions/seal/freeze traps).
Or make your properties non-configurable accessors.
A bit drastic and costly, but doable if defensiveness matters over
performance.
In both (1) and (2), I would want my object to behave the way the WeakMap
implementation behaves, not the Symbol way. Note that, though there are other
deviations the ES5 implementation makes, in both (1) and (2) the ES5 one
behaves the same as the WeakMap one -- the closure hides the internal state
from the unknownPrivateSymbol trap and protects it against freezing.
Initially, one of the things I loved about Symbols was that it allowed internal
state to be specified without using closures, so that prototypal inheritance
can be more fully relied upon. However, due to these considerations, I'm not
sure Symbols have much use to me anymore.
Thoughts?
Interaction between proxies and symbols have been carefully considered
and that shouldn't be a worry for you. The Proxy API has been designed
with preventing private symbols leaks. I don't think there is much that
can be done about the freezing problem than the 2 solutions I suggested
(which can be reasonable).
I think I've described how private names can be used equivalently to
weakmaps. There may be performance issues (though I don't know how
weakmaps perfs are at scale against the perf issues that would come with
the solutions I've suggested)
David
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss