Skip to main content

Symbol in JS

What Symbol is

Symbol is a primitive data type (introduced in ES6) representing a unique and immutable value.

It is created via a function:

javascript
const id = Symbol();

Every call to Symbol() creates a new unique value, even if the descriptions match.


Example

javascript
const id1 = Symbol('user'); const id2 = Symbol('user'); console.log(id1 === id2); // false

Although both symbols have the same description, 'user', they are different. Every Symbol() is unique.


Why Symbol is needed

Symbols are most often used as unique object property keys, to avoid name conflicts.


Example: ordinary keys can conflict

javascript
const user = { name: 'Oleh' }; user.id = 1; user.id = 2; // overwritten

But if you use Symbol:

javascript
const ID = Symbol('id'); const user = { name: 'Oleh', [ID]: 1 }; console.log(user[ID]); // 1

Now the property [ID]:

  • is unique;
  • is not visible during a normal iteration of properties.

Symbols do not take part in normal iteration

javascript
for (let key in user) { console.log(key); } // → "name"
javascript
console.log(Object.keys(user)); // ["name"]

A symbol does not appear in for...in, Object.keys(), or JSON.stringify().

But it can be retrieved:

javascript
console.log(Object.getOwnPropertySymbols(user)); // [Symbol(id)]

Symbols are often used "inside" the language

JavaScript has built-in (well-known symbols): special symbols that let you change the behavior of built-in operations.


Examples of built-in symbols:

SymbolUsed for
Symbol.iteratormakes an object iterable (for...of)
Symbol.toPrimitiveconfigures conversion to a primitive
Symbol.toStringTagsets the string returned by Object.prototype.toString
Symbol.hasInstanceoverrides the behavior of instanceof
Symbol.asyncIteratorlets you use for await...of

Example: Symbol.iterator

javascript
const arr = [1, 2, 3]; const iterator = arr[Symbol.iterator](); console.log(iterator.next()); // { value: 1, done: false }

The Symbol.iterator symbol makes an array "iterable": that is exactly what lets it work with for...of and spread (...arr).


Example: Symbol.toPrimitive

javascript
const user = { name: 'Oleh', age: 25, [Symbol.toPrimitive](hint) { return hint === 'string' ? this.name : this.age; } }; console.log(String(user)); // "Oleh" console.log(+user); // 25

The symbol lets you control how the object is converted to a number or a string.


Symbols can be stored in a "registry"

Sometimes a symbol with the same name needs to be the same one: that is what the global symbol registry is for.

javascript
const id1 = Symbol.for('user'); const id2 = Symbol.for('user'); console.log(id1 === id2); // true

Symbol.for(key) looks up the symbol in the global registry. If it is not found, it creates a new one and stores it under that key.

You can get the description like this:

javascript
Symbol.keyFor(id1); // 'user'

Symbols are safe "hidden" keys

They are ideal for:

  • creating private properties in libraries or classes;
  • extending objects without the risk of damaging someone else's data;
  • metadata (for example, in frameworks or an ORM).

Example of use in a class

javascript
const _id = Symbol('id'); class User { constructor(name) { this.name = name; this[_id] = Math.random(); } } const user = new User('Oleh'); console.log(user); // { name: 'Oleh', [Symbol(id)]: 0.123... } console.log(Object.keys(user)); // ["name"]

The symbol makes the _id field invisible during normal iteration and protects it from being accidentally overwritten.


Summary

PropertyDescription
TypePrimitive
UniquenessEvery Symbol() is unique
Used asA key for object properties
Not visiblein for...in, Object.keys(), JSON.stringify()
Has a global registryvia Symbol.for() and Symbol.keyFor()
Examples of built-in symbolsSymbol.iterator, Symbol.toPrimitive, Symbol.hasInstance, and others

In short

  • Symbol() creates a unique value, even with an identical description.
  • It is used for unique keys of properties.
  • It does not take part in normal iteration, so it is convenient for "private" data.
  • It has built-in variants (Symbol.iterator, Symbol.toPrimitive, and others) that let you change the behavior of standard JS operations.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.