Back to JavaScript Notes
Topic #352

Symbols

By the end of this lesson, you will be able to create JavaScript Symbols and use them as collision-proof property keys for hidden metadata, private-ish object fields, and protocol hooks.

What it is

A Symbol is a primitive value created with Symbol(description). The description is only a label for debugging; it does not make the symbol equal to another symbol with the same description. Each call to Symbol() returns a new unique value, so two symbols can never collide unless you intentionally reuse the same symbol or use the global symbol registry with Symbol.for().

Think of a symbol as a secret key name. If you store data under a symbol key, ordinary string keys cannot accidentally read or overwrite it. Symbols are often used for object property keys, but they can also be used as values, map keys, or protocol markers such as Symbol.iterator.

Why it matters

  • Prevents accidental property-name collisions when libraries add metadata to objects.
  • Creates hidden object properties that are skipped by Object.keys(), for...in, and JSON.stringify().
  • Supports JavaScript protocols, such as iteration with Symbol.iterator and primitive conversion with Symbol.toPrimitive.
  • Provides a lightweight way to represent unique enum-like values without exposing them as strings.

Syntax or steps

  1. Create a unique symbol: const id = Symbol("id");.
  2. Use it as a computed property key: { [id]: value }.
  3. Read it with bracket notation: object[id].
  4. If you need the same symbol across modules or realms, use Symbol.for("name") instead of Symbol("name").

Example

const id = Symbol("id");
const role = Symbol("role");

const user = {
  name: "Ada",
  [id]: 42,
  [role]: "admin"
};

console.log(user.name);        // Ada
console.log(user[id]);         // 42
console.log(Object.keys(user)); // ["name"]

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

const shared = Symbol.for("shared");
const alsoShared = Symbol.for("shared");
console.log(shared === alsoShared); // true

const unique = Symbol("shared");
console.log(shared === unique);     // false

The object has one normal string property, name, and two symbol-keyed properties. Object.keys() returns only string keys, so the symbol properties are hidden from ordinary enumeration. Object.getOwnPropertySymbols() can reveal them if you have the symbol values. Symbol.for() looks up or creates a symbol in a global registry, so the same description returns the same symbol. Symbol() always creates a new symbol, even if the description matches.

Common mistakes

  • Using new Symbol(). Symbols are primitives and are not constructed with new; use Symbol().
  • Assuming the description makes symbols equal. Symbol("id") === Symbol("id") is false.
  • Expecting symbol properties to appear in JSON.stringify(). They are omitted, so use a normal string property if the data must be serialized.
  • Using Symbol.for() when you need true uniqueness. The registry is shared, so two unrelated libraries using the same key can collide.

When to use it

Use symbols when you need a property key or marker that should not collide with ordinary string keys. Use strings when the key is part of the public data shape, needs to be serialized, or should be easy to inspect.

NeedUseWhy
Hidden metadata on an objectSymbol()Not enumerated by normal string-key APIs.
Shared marker across modulesSymbol.for()Same registry key returns the same symbol.
Public JSON fieldString keyJSON supports string keys, not symbol keys.
Custom iterationSymbol.iteratorJavaScript looks for this built-in symbol.

Practice

Guided exercise: create a symbol called secret, store it on an object with a visible name property, then print the object's string keys and symbol keys.

const secret = Symbol("secret");
const account = { name: "main", [secret]: "1234" };

console.log(Object.keys(account));
console.log(Object.getOwnPropertySymbols(account));

Expected output: ["name"], then an array containing Symbol(secret).

Challenge: create two symbols with the description "token" and prove they are different. Then create two Symbol.for("token") values and prove they are the same.

Quick check

Question: Why does Symbol("id") === Symbol("id") return false?

Answer: Because each call to Symbol() creates a new unique primitive. The description is only a debugging label, not an identity.

Summary

Symbols give JavaScript a way to create unique, non-colliding identifiers, especially useful as hidden property keys and protocol hooks. Use Symbol() for uniqueness and Symbol.for() only when you intentionally want a shared symbol.

Want to go beyond the notes?

Join Coding Now Tech Institute's JavaScript course — live mentorship, real projects, and 100% placement support.

Enroll Now — Free Demo Available

Symbols – FAQs

Quick answers about learning Symbols in JavaScript.

This free note from Coding Now Tech Institute explains Symbols in JavaScript — concept, syntax and worked code examples you can copy, run and revise before interviews.
Yes. Every JavaScript topic on Coding Now Tech Institute, including Symbols, is 100% free with no signup required.
With focused practice, most students grasp Symbols in 1–3 days from these notes; pairing it with Coding Now Tech Institute's mentor-led course takes you to job-ready depth faster.
Use the code examples in this note, then ask doubts for free on the Coding Now Tech Institute Community (/community) — expert instructors answer within 24 hours.
Call NowEnroll Now