> 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: // ES5 function SimpleDate(timestamp) { timestamp = +timestamp; this.setTime = function setTime(time) { timestamp = +time; } this.getTime = function getTime() { return timestamp; } } Trying to rewrite it in ES6 produces these possibilities: // ES6 Symbols // Forgive me for not knowing what the current // correct syntax is for creating a symbol: let timestamp = new Symbol(); class SimpleDate { construct(time) { this.setTime(time); } setTime(time) { this[timestamp] = +time; } getTime() { return this[timestamp]; } } // ES6 WeakMap let timeMap = new WeakMap(), // Store WeakMap methods to maintain integrity of the internal state. WeakMapGet = Function.prototype.call.bind(WeakMap.prototype.get), WeakMapSet = Function.prototype.call.bind(WeakMap.prototype.set); class SimpleDate { construct(time) { this.setTime(time); } setTime(time) { WeakMapSet(timeMap, this, +time); } getTime() { return WeakMapGet(timeMap, this); } } 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. 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). It sounds to me like if I am writing defensive library code, I will always want to use a WeakMap instead of a Symbol. 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? _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss