Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding ES6 Symbols

I've been around the block when it comes to languages, having worked with everything from C# to Lisp to Scala to Haskell, and in every language that supported them, symbols have acted pretty much the same; that is, any two symbols with the same name, are guaranteed to be identical because they're singleton objects.

Racket: (equal? 'foo 'foo) true

Common Lisp: (eq 'foo 'foo) true

Ruby: :foo == :foo true

Scala: 'foo == 'foo true

ES6: Symbol('foo') === Symbol('foo') false

The benefit of symbols being singletons is obvious: You can use them in maps/dictionaries without risking your key not being equal to your input because the language suddenly decided to hash it differently (looking at you, Ruby)

So why is it that ECMAScript 6 takes a different approach on this, and how can I get around it?

like image 763
Electric Coffee Avatar asked Nov 22 '15 15:11

Electric Coffee


People also ask

What are symbols in ES6?

Symbols are new primitive type introduced in ES6. Symbols are completely unique identifiers. Just like their primitive counterparts (Number, String, Boolean), they can be created using the factory function Symbol() which returns a Symbol. Every time you call the factory function, a new and unique symbol is created.

What do the symbols mean in JavaScript?

Symbol is a primitive data type of JavaScript, along with string, number, boolean, null and undefined. It was introduced in ECMAScript 2015, so just a few years ago. It's a very peculiar data type. Once you create a symbol, its value is kept private and for internal use.

What is '$' in JavaScript?

Updated on July 03, 2019. The dollar sign ($) and the underscore (_) characters are JavaScript identifiers, which just means that they identify an object in the same way a name would. The objects they identify include things such as variables, functions, properties, events, and objects.

What is the motivation for bringing symbols to ES6?

It was important to maintain unique object keys to prevent the overwriting of values having similar object key as this could result in loss of data. The introduction of Symbol helped overcome this problem as unique keys could be generated without writing a complicated piece of code.


1 Answers

You can (sort-of) get the effect of symbols being "knowable" by name by using registered (global) symbols:

var s1 = Symbol.for("foo");
var s2 = Symbol.for("foo");
s1 === s2; // true

Of course you can create your own Symbol registry too, with a Map instance or a plain object.

edit — I'll add that the intention of the optional string parameter when making a new Symbol instance is to provide a way of identifying the meaning and purpose of a symbol to the programmer. Without that string, a Symbol works just fine as a Symbol, but if you dump out an object in a debugger the properties keyed by such anonymous Symbol instances are just values. If you're keeping numeric properties on an object with Symbol keys, then you'll just see some numbers, and that would be confusing. The description string associated with a Symbol instances gives the programmer reference information without compromising the uniqueness of the Symbol as a key value.

Finally, you can always compare the result of calling .toString() on two similarly-constructed Symbol instances. I suspect that that practice would be considered questionable, but you can certainly do it.

edit more — it occurs to me that the fact that the default behavior of Symbol creation in JavaScript makes the type more useful than, say, atoms in Erlang or keys in Clojure. Because the language provides by default a value guaranteed to be unique, the fundamental problem of namespace collision is solved pretty nicely. It's still possible to work with "well-known" symbols, but having unique values available without having to worry about conflicts with other code that might also want to avoid collisions is nice. JavaScript has the somewhat unique, and certainly uniquely pervasive and uncontrollable, problem of a global namespace that may be polluted by code that a programmer does not even know exists, because code can collide in the browser enviroment due to the actions of a party different from, and unknown to, an arbitrary number of software architects.

like image 109
Pointy Avatar answered Sep 21 '22 02:09

Pointy