Javascript Symbols, the Basics

What is a Javascript symbol? and why would I ever need to use one? We’re going to cover the very basic principles of that here
A Symbol is a primitive value, just like strings, numbers, booleans, undefined, and null. And just like those other primitive values, a symbol itself is immutable. You can of course alter a variable that points to any of these values, but the value itself can not be changed. For example, you can’t redefine the number 1, and true will always be true.
But symbols are also like objects, in that they are created. When you want to use a symbol, you instantiate a new one. This means that each time you create a symbol, you’re creating a new, immutable primitive value. Note that the argument passed in is that symbols description, and is generally used for debugging purposes.
As you can see here, even symbols that look exactly the same are actually different pieces of data. Every time a symbol is created, you can imagine it has its own unique identifier, that differentiates it from any other symbol. Just keep in mind, you can’t instantiate a symbol with the new
operator like you would a function or a class. Just call Symbol()
for instantiation.
And where might these symbols be useful? One great place to use a symbol is as an object property. Symbols were introduced in ES2015, and had to be backwards compatible. To do this, symbols had to be outright ignored in for..in loops, (and also in the JSON.stringify method, as JSON only supports string keys). This allows you to set “secret” properties onto objects, that can be accessed if need be, but will not alter the “shape” or business logic of that property. For instance, if you wanted some data that describes the object, but isn’t necessary when passing the object around to perform calculations, a symbol is a great choice. But remember, even if the for..in loop doesn’t know about your symbol, you can still check for all symbols on an object. This is why “secret” is in quotations, and why you should never try to hide sensitive data inside one.
Another good use for symbols is big sets of data. For instance, if you’re creating a lot of key-value pairs on an object, it may be hard to find unique names for each individual key. Even if you were to generate random strings for your keys, you still run the risk of a collision somewhere down the line. Since every symbol is unique, if you set the keys with symbols, you don’t ever have to worry about replacing data instead of adding it.
It’s important to remember that there is also another variation of the JavaScript symbol. We can also create global symbols that can be accessed throughout your entire codebase. These global symbols are different, in that they are not all unique instances of a symbol, but are unique to the key arguments passed in to them. When you call Symbol.for(“description”)
, you are either returned the pre-existing global symbol, or the new symbol if it hasn’t been created yet. You can also call Symbol.keyFor(symbol)
, where you pass in a symbol. If that symbol exists globally, you will be returned its “key” or “description”, otherwise you’re just returned undefined
.
There are plenty of static and instance methods associated with symbols that can make your life easier, and are worth checking out. And while symbols may not be something you reach for in your day to day coding, they can certainly be useful in the right circumstances.