Rick Waldron (2013-09-26T21:01:35.000Z)
domenic at domenicdenicola.com (2013-10-13T02:27:38.591Z)
On Thu, Sep 26, 2013 at 9:11 AM, Kevin Smith <zenparsing at gmail.com> wrote: > After thinking this over, I still remain unconvinced that symbols are the > right solution to the problem. Besides the fact that they introduce (ever > more) complexity to the object model, they simply do not work as a > duck-typing strategy for the real, *multi-realm* world of Javascript. > Sure, we can make a special case of standard library symbols such that > they maintain identity across realms. But a solution which only works for > special cases isn't a very good solution, is it? > The consensus included Allen writing proposal for user-defined well-known symbol registration—these symbols would also maintain identity across realms. https://github.com/rwaldron/tc39-notes/blob/master/es6/2013-09/sept-18.md#consensusresolution-1 > Here is another proposal which avoids these pitfalls: > > 1) Identify all meta-layer hooks using a string that is not an identifier. > The actual string used doesn't matter in this proposal, but for > illustration purposes I'll use an "@"-prefix. > > 2) Define all meta-layer hooks as functions. Testing for the hook will > involve [[Get]] followed by [[IsCallable]]. > > For example, defining an iterable: > > class C { "@iterator"(...args) { /* ... */ } } > > Overriding the string tag: > > class C { "@toStringTag"() { return "[object C]"; } } > > - Since the property name is a non-identifer, it is unlikely to collide > with any object members. > But these can still easily collide with <identifier-name-string> property access (of the same string name), so I don't understand how this is better, can you clarify? - Since the value of the hook must be a function, it is unlikely to collide > with keys in an object-as-map (e.g. a JSON object). > What about something like this? ```js // event.js let events = Symbol(); export class Emitter { constructor() { this[events] = Object.create(null); } on(type, handler) {...}, off(type, handler) {...} emit(type, ...args) {...} } // program.js import { Emitter } from "event"; class Serialport extends Emitter { constructor() { super(); // there is no way to accidentally pave // over the `events` symbol property } } ``` If I try that with your proposal: ```js // event.js export class Emitter { constructor() { this["@events"] = Object.create(null); } on(type, handler) {...}, off(type, handler) {...} emit(type, ...args) {...} } // program.js import { Emitter } from "Event"; class Serialport extends Emitter { constructor() { super(); this["@events"] = "MINE"; } } ```