Table of contents
Ever heard of the Symbol
type in JavaScript. I don't expect you to, it's pretty unknown. I happened to stumble upon it just a week back. Let me tell you some more about Symbols!
What is it?
A Symbol
is a unique identifier inside of JS. It's a primitive data type, meaning it is not an object and has no methods or properties.
They're used to uniquely identify particular strings or other values. A Symbol
can be created as follows:
let sym = Symbol("sym")
The string passed as a parameter to the Symbol()
function is called the description of the symbol. The description of the Symbol is optional. Even if two symbols have identical descriptions, they're not identical Symbols, since each is a unique identifier.
let sym1 = Symbol("sym")
let sym2 = Symbol("sym")
console.log(sym1 == sym2) // false
You cannot log Symbols directly. However, you can use .toString()
to convert it to a string first and then log it.
let sym1 = Symbol("sym")
console.log(sym) // TypeError: Cannot convert a Symbol value to a string
console.log(sym.toString()) // logs Symbol(id)
console.log(sym.description()) // logs "sym"
Why?
Let's say we wanted to create a hidden property of an object. A hidden property means that this property cannot be easily accessed or overwritten. Only when the codebase contains that specific Symbol can they access the said property. This is especially useful when we're getting some data from an external codebase and we don't want to modify said data.
Let me demonstrate:
let user = { name: 'Shivank' }
let country = Symbol()
user[country] = 'IND'
user.country = 'IND'
user.country = 'UK'
// BOOM! Overwritten
There will be no conflict between our and their identifiers, because symbols are always different, even if they have the same name.
To use symbols in an object literal, we encapsulate it in square brackets as follows:
let country = Symbol()
let user = { name: 'Shivank', [country]: 'IND' }
console.log(user) // { name: "Shivank", Symbol(country): 'IND' }
Symbols are also hidden when the object's keys are referenced. However, Object.assign()
copies both string and symbol properties.
let country = Symbol()
let user = { name: 'Shivank', age: 5, [country]: 'IND' }
for (let key in user) console.log(key) // name, age (no symbols)
for (let key in Object.keys(user)) console.log(key) // same result
Global Symbols
To have same-named Symbols or Symbols with the same description be the same entities, you can use the Global Symbol Registry in JS. Symbol.for("key")
would check if a specific key called key
exists in the Global Symbol Registry. If it does, it just reads it. Or else, it creates it and reads it. Symbol.keyFor(variable)
reads the value or description of that key.
let key = Symbol.for('key') // Gets created and read
let sameKey = Symbol.for('key') // Read
console.log(key === sameKey) // True
console.log(Symbol.keyFor(key)) // 'key'
Conclusion
Symbols do come in pretty handy if you're working with fragile data or data that you don't want to affect by overwriting. This will come in pretty handy for all the developers out there working with tons of API data or database data. If you'd like to learn more about the Symbol type, check out these articles by MDN and javascript.info.
Thanks for reading! I welcome any feedback in the comments, so don't hesitate to write something helpful. If you'd like to learn more about JavaScript, check out more of my blog posts below as well as my blog page.