ES6 Symbols in Depth
ponyfoo.com
ponyfoo.com
function match(t, matchers) {
const variant = t[Symbol.for('variant')];
return matchers[variant](t);
}
Previously one had to make the sum look something like { _variant: String
, _params: Obj
}
to ensure that you could work generically with them and not have the _params object accidentally clobber your variant. Underscore privates are nice, but... obviously a hack.https://hacks.mozilla.org/category/es6-in-depth
(note it's extremely similar to this one, both are guides on ES6 and cover pretty much all the areas)
Why? That seems inconsistent with other JavaScript constructors.
var s = new String('foo');
typeof s; // 'object'
That is, when you use the `new` keyword, you get back an object instead of a primitive. Since symbols are always primitives, disallowing the `new` keyword actually prevents inconsistency with the rest of the language in the sense that it doesn't allow you to create non-objects with a constructor.I'm not really sure why you'd use new String anyway - it won't always act as a string primitive. Rather than making Symbol reimplement the same quirks that other built in constructors do, isn't not allowing a Symbol constructor going to avoid a lot of confusion?
For example, if you created an object using a hypothetical symbol constructor, the symbol would be converted to a string if you tried to use it as an object key (internally, JavaScript sees your symbol object as an object, not a symbol), which is simply creating problems for a naive programmer.
[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
What do you mean? That new Symbol() should just ignore the 'new'?
console.log(Boolean(5)); // true
console.log(Number("5")); // 5
console.log(String(1)+1); // "11"
Using new with any of the other primitive functions takes the return value and creates it into an object with the primitive function's prototype, which is kind of a coincidence it looks like it does anything useful but can cause a lot of issues because primitives and objects are different. If backwards compatibility weren't king, I'd expect to see that get removed. Instead, the best they can do is make any new primitive functions throw a TypeError if used with `new`.I'd be surprised if being able to use `new` with the other primitive functions was ever specifically intended and if that choice to allow it wasn't regretted. It's a common source of confusion and is not useful.
Mixing symbols in for something that seems asymptotic is the strange part.
Should I try harder to see the usefulness of it?
Right now all it seems to have done for me is make it impossible to use NPM modules because everything is targeting a different runtime and stuff that expects JavaScript breaks other libraries that expect ES6 and vice versa. I'm forced now to use what feels like a beta language in production because a handful of key libraries now require ES6.
I am seriously considering just forking every library that ports to ES6, which is preposterous, but I don't know what else to do. The whole point of JavaScript in my mind was that it runs everywhere, on every obscure browser and any machine with a node executable. ES6 has ruined what was Javascript's most unique and most powerful feature.
Now we have a bloated spec. Seriously. Fat arrow syntax with explicit scope? Bind() works just fine, thank you.
And this isn't about fear of change. Change should only be for legitimate purpose. When I detect any trace of change for stylistic issue, I snear.