Data types in depth - Symbols

When we talk about data types in JavaScript, we often mention numbers, strings, booleans, or even objects. But there's one special data type that tends to fly under the radar—the Symbol
.
What is the "symbol" datatype? I am sure most of the experienced devs reading this haven't used this a lot too, but in this article we will dive deep into the "what" and "how" of using the Symbol, so buckle up!
What is a Symbol?
In a nutshell, a Symbol is a unique and immutable primitive data type introduced in ES6 (ECMAScript 2015). Phew! Let's simply that shall we?
Each time you create a Symbol, it’s guaranteed to be different—even if you create two symbols with the same description. Think of it like a VIP ID card; each card might say "VIP," but each card is unique and represents a different person.
let symbol1 = Symbol('VIP');
let symbol2 = Symbol('VIP');
console.log(symbol1 === symbol2); // false
See? Even though both symbols have the same label ('VIP'), they are distinct and will never collide.
Now, why would we need this? Let’s look at an example from our daily lives in India.
Imagine you’re running a school in Bangalore, and you need to uniquely identify each student. You could use their names, but names can sometimes overlap. In India, many students might have the same name like “Rahul” or “Priya.” You don’t want to run into issues where multiple “Rahul Kumar” students get mixed up. What you need is something unique to each individual, like their Aadhaar number. Even if two students have the same name, their Aadhaar numbers will be unique. In JavaScript, this is where Symbols come in handy.
Let's say we have a list of students, and we want to assign each a unique ID:
let student1 = {
name: 'Rahul Kumar',
id: Symbol('AadhaarID')
};
let student2 = {
name: 'Rahul Kumar',
id: Symbol('AadhaarID')
};
console.log(student1.id === student2.id); // false
Even though both students have the same name, their IDs are unique. The symbol guarantees that no two students will be confused with one another, much like how the Aadhaar card guarantees that every Indian citizen is uniquely identified.
Symbol as Object Properties
In JavaScript, Symbols are often used as unique keys for object properties. This is particularly useful when you want to ensure that a property key won’t accidentally conflict with other keys in the object.
The School Example (Continued)
Suppose we have two classes, and each class has some common properties like “name,” “teacher,” and “room number.” Now, you want to add an internal property to each class object that stores the head of the Parent-Teacher Association (PTA). You don’t want this property to clash with any existing properties.
let classA = {
name: 'Class A',
teacher: 'Mrs. Sharma',
room: '101',
[Symbol('PTA Head')]: 'Mr. Singh'
};
let classB = {
name: 'Class B',
teacher: 'Mr. Nair',
room: '102',
[Symbol('PTA Head')]: 'Mrs. Mehta'
};
console.log(classA); // { name: 'Class A', teacher: 'Mrs. Sharma', room: '101', [Symbol('PTA Head')]: 'Mr. Singh' }
console.log(classB); // { name: 'Class B', teacher: 'Mr. Nair', room: '102', [Symbol('PTA Head')]: 'Mrs. Mehta' }
By using Symbols as keys, you avoid any potential collisions between keys, even if another developer decides to add a property called “PTA Head” to the object later on. It’s like ensuring that your school has unique room numbers for each class—even if two rooms are used for different purposes, their unique IDs will prevent confusion.
Symbols and Object Privacy
Symbols can also provide a level of “pseudo-privacy” to object properties. Although these properties are not fully private (you can still access them if you know the Symbol), they are not easily discoverable using traditional methods like Object.keys()
or for...in
loops.
Let's see the school example again
Let’s say you don’t want to publicly expose the name of the PTA head. You could use a Symbol to ensure that this property doesn’t show up when you enumerate over the object’s properties.
let classC = {
name: 'Class C',
teacher: 'Mrs. Iyer',
room: '103',
[Symbol('PTA Head')]: 'Mr. Raj'
};
for (let key in classC) {
console.log(key); // Will only log 'name', 'teacher', 'room', but not 'PTA Head'
}
console.log(Object.keys(classC)); // ['name', 'teacher', 'room']
Even though the PTA head is part of the object, it won’t be revealed unless you explicitly access it via the Symbol. It’s like keeping certain information restricted to the school’s management team. Not everything has to be visible to everyone! (Like your chat with your best friend!)
Global Symbols
JavaScript also provides a Symbol.for()
method that allows you to create symbols that are globally shared. While the symbols created with Symbol()
are always unique, those created with Symbol.for()
are not. This method checks whether a symbol with the given key already exists; if it does, it returns that symbol. If not, it creates a new one.
Let’s modify our Aadhaar example to use a globally shared symbol for the same student:
let aadhaarRahul = Symbol.for('RahulAadhaar');
let student3 = {
name: 'Rahul Kumar',
id: aadhaarRahul
};
let student4 = {
name: 'Rahul Kumar',
id: Symbol.for('RahulAadhaar')
};
console.log(student3.id === student4.id); // true
The Symbol.iterator
allows us to create a custom iterable object. Much like how school attendance is taken, this mechanism ensures that all students are accounted for, one by one, in an orderly fashion.
Let's do a quick recap, shall we?
Let’s take a quick breather and recap the key points:
- Unique Identifiers: Just like Aadhaar ensures unique IDs for citizens, Symbols ensure that property keys are always unique.
- Private Data: Symbols allow you to hide certain properties from prying eyes, similar to restricting sensitive school information like PTA heads to only relevant staff.
- Global Symbols (Reusable Aadhaar IDs):
Symbol.for()
lets you create globally reusable symbols, much like how Aadhaar is a common identifier across institutions. - Custom Iterables (Taking Attendance): You can use symbols like
Symbol.iterator
to define how your object should be iterated, just like marking attendance for students.
Libraries and Frameworks
Note: This is additional info if you know ReactJS or heard of it, if not don't worry, you can read it and understand as much as you can, the rest will come to you in due time!
Symbols are often used in popular JavaScript libraries and frameworks like React. For instance, React uses Symbols internally to identify specific elements or types, helping prevent clashes with other parts of the application. This ensures that different components, hooks, and methods remain unique and don't interfere with each other—just like how our unique Aadhaar card system keeps people distinct, even if they have the same name.
Meta-Programming
Symbols are useful in meta-programming techniques where you want to add metadata or behavior to objects without interfering with the regular properties. For instance, in APIs, you might use Symbols to attach special metadata to requests without affecting the existing object structure.
So, was it an interesting topic? In software development, just like in real life, "conflicts hote rehte hai" (translated to English: conflicts keep happening), but we need to ensure to use the best practices like using symbols to resolve or avoid those conflicts.
I hope this topic was clear to you, lets move on to the next one?