Symbols

In your class, there might be two students named "Rahul Sharma". 👥

Same name, but they are different people. How does the school tell them apart? Each student has a unique roll number or Aadhaar number. Even if the names match, the numbers never do.

JavaScript has a special value that works just like that unique number. It is called a Symbol.


What Is a Symbol?

📝 Definition: A Symbol is a primitive data type in JavaScript that represents a unique and unchangeable value. Every Symbol you create is different from every other Symbol, even if they have the same description.

Symbols were added to JavaScript in ES6 (2015). It is one of the 7 primitive data types:

Key points to remember 📌

  • A Symbol is always unique. No two Symbols are ever equal.
  • A Symbol is a primitive, not an object.
  • Its main use is as a special object key that never clashes with other keys.
  • Symbol keys are hidden from normal loops and Object.keys().

Why Do We Need Symbols?

Imagine you're working on a big project with many developers. 👨‍💻👩‍💻 Everyone adds properties to the same user object.

Normal string keys can clash by accident. 💥

Now with a Symbol key, there is no clash:

Both "id" values live happily together, because a Symbol key is unique. 🤝


Creating a Symbol

Use the Symbol() function.

const mySymbol = Symbol();
const id = Symbol("id");   // with a description

The description

The text inside Symbol("...") is called the description. It's just a label to help you when debugging. It does not make the symbol unique, and it does not affect the value.

⚠️ Don't use new with Symbol

Symbol() is a function that returns a primitive, not a constructor that builds an object. So always write Symbol(), not new Symbol().


Symbols Are Always Unique

This is the most important thing about Symbols.

Compare this with strings:


Using Symbols as Object Keys

To use a Symbol as a key, put it in square brackets [ ]. This is a computed property.

⚠️ Always use bracket notation obj[symbol] to read a symbol key. Dot notation obj.symbol looks for a normal string key instead.

Adding a symbol key later


Symbol Keys Are Hidden 🙈

Symbol keys don't show up in the usual places. This makes them great for "behind-the-scenes" data.

PlaceShows symbol keys?
for...in loop❌ No
Object.keys() / values() / entries()❌ No
JSON.stringify()❌ No
obj[symbol]✅ Yes
Object.getOwnPropertySymbols()✅ Yes
Reflect.ownKeys()✅ Yes (all keys)

Finding symbol keys

🔐 Hidden is not the same as private! Anyone can still find symbol keys using Object.getOwnPropertySymbols(). Symbols help avoid accidents. They are not a security feature.

Copying keeps symbol keys

The spread operator ... and Object.assign() do copy symbol keys.


Global Symbols: Symbol.for()

Sometimes you want to share the same symbol in different parts of your app. For that, JavaScript keeps a global symbol registry, like a common notice board 📋 that everyone can read.

Symbol.for("key"):

  • looks for a symbol with that key in the registry
  • if it exists, returns it
  • if not, creates a new one and saves it

Symbol.keyFor()

Gets the key name of a global symbol.

Symbol() vs Symbol.for()

PointSymbol("x")Symbol.for("x")
Creates a new symbol every time?✅ Yes❌ No, reuses it if it exists
Two calls equal?❌ Never✅ Yes
Stored in the global registry?❌ No✅ Yes
Symbol.keyFor() works?❌ No✅ Yes

Symbols Can't Be Auto-Converted to Text

Symbols refuse to be automatically turned into strings or numbers. This prevents accidental mistakes.


Real-Life Use Cases

1. Unique constants (instead of plain strings)

When you need fixed options that should never be confused with normal text, use Symbols.

A random string like "shipped" can't accidentally match. Only the real symbol works. 🎯

2. Adding safe extra data to objects

Add your own information to an object from someone else's code, without the risk of overwriting their properties.

3. Customising built-in behaviour (well-known symbols)

JavaScript has some built-in symbols that let you change how your objects behave. Let's look at them next!


Well-Known Symbols

JavaScript has built-in symbols, called well-known symbols, that control how objects work behind the scenes. You write them like Symbol.name.

SymbolWhat it controls
Symbol.iteratorHow for...of and spread ... go through your object
Symbol.toPrimitiveWhat happens when your object is turned into a number or string
Symbol.toStringTagThe name shown by Object.prototype.toString()
Symbol.asyncIteratorHow for await...of works (advanced)

Symbol.iterator: make your object work with for...of

Normally, a plain object can't be used with for...of.

But if you add a Symbol.iterator method, it can!

The * and yield make this a generator function. You will learn generators in a later lesson. For now, just see how Symbol.iterator makes for...of work.

Symbol.toPrimitive: control conversion

Symbol.toStringTag: a custom type name

💡 Well-known symbols are advanced. As a beginner, just remember that Symbol.iterator is what makes arrays, strings, Maps, and Sets work with for...of.


Common Mistakes to Avoid

MistakeProblemFix
new Symbol("id")❌ TypeError: not a constructorUse Symbol("id")
Expecting Symbol("a") === Symbol("a")Always falseStore the symbol in a variable and reuse it, or use Symbol.for()
Reading with obj.mySymbolGets undefinedUse obj[mySymbol]
"Text " + symbol❌ TypeErrorUse symbol.toString() or symbol.description
Expecting symbol keys in Object.keys() or JSONThey are hiddenUse Object.getOwnPropertySymbols()
Using symbols to hide secretsAnyone can still find themUse real private fields (#secret) in classes
Losing the symbol variableYou can't read the value easily anymoreKeep a reference to the symbol

Quick Summary Table

TaskCode
Create a symbolconst id = Symbol("id");
Read its descriptionid.description
Use it as a keyconst obj = { [id]: 123 };
Read a symbol keyobj[id]
Find all symbol keysObject.getOwnPropertySymbols(obj)
Get or create a global symbolSymbol.for("appId")
Get a global symbol's keySymbol.keyFor(sym)
Convert to textid.toString()
Check the typetypeof id === "symbol"
Make an object iterable[Symbol.iterator]() { ... }

Key Takeaways

  • A Symbol is a primitive data type that is always unique. Symbol("id") === Symbol("id") is false.
  • The text in Symbol("...") is only a description for debugging. It doesn't affect uniqueness.
  • Symbols are mainly used as object keys that never clash. Read them with bracket notation obj[sym].
  • Symbol keys are hidden from for...in, Object.keys(), and JSON.stringify(), but they are not truly private.
  • Use Symbol.for() to share one symbol across your app, and well-known symbols like Symbol.iterator to customise how JavaScript works with your objects.