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

Reply via email to