ES6+ (Modern JavaScript) · Structure

Symbols

A Symbol is a value that is guaranteed to be unique. It sounds abstract, but symbols are how JavaScript lets you plug your own objects into language features like for…of.

Intermediate 5 min Lesson 13 of 23 Runnable examples
Before you start:Enhanced Object Literals
0/23 in ES6+
On this page · 5 min · Intermediate

Learning objectives#

  • Create symbols and use them as object keys
  • Explain why symbol keys do not clash
  • Use Symbol.for for shared symbols
  • Customise behaviour with well-known symbols

Explanation#

Symbol("id") creates a brand-new unique value. Two symbols with the same description are still different: Symbol("x") !== Symbol("x").

Used as an object key, a symbol cannot clash with any string key or with another library’s symbol. Symbol keys are skipped by Object.keys, for…in and JSON.stringify.

Symbol.for("app") looks up a global registry: the same name always returns the same symbol, even across files.

Well-known symbols are hooks into the language: Symbol.iterator makes an object work with for…of and spread; Symbol.toPrimitive controls how an object converts to a string or number.

Syntax#

JavaScript Illustrative
const id = Symbol('id');
const obj = { [id]: 123 };
obj[id]; // 123

Code example: Unique keys and language hooks#

JavaScriptUnique keys and language hooks Runnable
const id = Symbol('id');
const user = { name: 'Asha', [id]: 101 };
console.log(user[id]);
console.log(Object.keys(user));
console.log(JSON.stringify(user));


console.log(Symbol('x') === Symbol('x'));
console.log(Symbol.for('app') === Symbol.for('app'));


class Temperature {
  constructor(c) { this.c = c; }
  [Symbol.toPrimitive](hint) {
    return hint === 'string' ? `${this.c}°C` : this.c;
  }
}
const t = new Temperature(30);
console.log(`${t}`, t + 5);
Expected output
101
[ 'name' ]
{"name":"Asha"}
false
true
30°C 35
Opens this example in the full playground

Step-by-step explanation#

  1. The symbol key stores 101 and is read with user[id].
  2. Object.keys and JSON.stringify ignore symbol keys — the id stays hidden.
  3. Two Symbol() calls are always different.
  4. Symbol.for returns the same registered symbol for the same name.
  5. Symbol.toPrimitive decides the conversion: string in a template literal, number in maths.

Real-world use case#

Libraries attach metadata to your objects with symbol keys so they never overwrite your own properties; custom collections implement Symbol.iterator.

Common mistakes#

Expecting symbols in JSON

JSON.stringify drops symbol keys. Use string keys for data you send to a server.

Treating symbols as private

Object.getOwnPropertySymbols(obj) reveals them. Use #private class fields for real privacy.

Using new Symbol()

Symbol is not a constructor; new Symbol() throws a TypeError. Call Symbol() directly.

Best practices#

  • Use symbols for metadata keys that must not clash
  • Use well-known symbols to integrate with language features
  • Always give symbols a description for debugging
  • Use Symbol.for only when sharing across modules is intended

Remember this#

Symbol = a one-of-a-kind ID tag.

Hidden from keys, loops and JSON — but not truly private.

Symbol.iterator = “I can be looped”. Symbol.toPrimitive = “here is how to convert me”.

Practice exercise#

Your task: Create a Money class whose instances print as "₹500" in template literals and behave as 500 in arithmetic.

Need a hint?
Implement [Symbol.toPrimitive](hint).
Show solution
JavaScript Runnable
class Money {
  constructor(amount) { this.amount = amount; }
  [Symbol.toPrimitive](hint) { return hint === 'string' ? `₹${this.amount}` : this.amount; }
}
const m = new Money(500);
console.log(`${m}`, m * 2); // ₹500 1000
Opens this example in the full playground

Mini quiz#

Symbols quizPredict the output Question 1 of 3

What is printed?

console.log(Symbol('a') === Symbol('a'));
Score so far: 0/0

Want more? Practise all ES6+ MCQs · ES6+ interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.