The Codex / JavaScript / Symbols

Symbols

JavaScript's unique identifier primitive — Symbol(), well-known symbols, Symbol.iterator, Symbol.for, and using symbols as private-ish object keys.

What it is, in plain English: A Symbol is a primitive value that is guaranteed to be unique — no two Symbols are ever equal, even if created with the same description. Symbols are used as object property keys that can't accidentally collide with other keys. Well-known Symbols (Symbol.iterator, Symbol.toPrimitive, Symbol.hasInstance...) let you hook into JavaScript's built-in behaviours.

Unique keys that never collide

JavaScript objects can have properties keyed by strings or Symbols. String keys can clash — if two pieces of code both add a "id" property, one overwrites the other. A Symbol is guaranteed unique — even two Symbols created with the same description are different values.

Creating Symbols

const sym1 = Symbol("description");   // the description is just for debugging
const sym2 = Symbol("description");

console.log(sym1 === sym2);   // false — ALWAYS different
console.log(typeof sym1);     // "symbol"
console.log(sym1.description); // "description" — the label you gave it
console.log(sym1.toString());  // "Symbol(description)"

// You cannot new Symbol() — it's not a constructor:
// new Symbol()  // TypeError: Symbol is not a constructor

Using Symbols as object keys

const SECRET = Symbol("secret");
const ID     = Symbol("id");

const user = {
  name:     "Alice",
  [SECRET]: "password123",   // computed property syntax for Symbol keys
  [ID]:     42,
};

// Access with the Symbol reference:
console.log(user[SECRET]);   // "password123"
console.log(user[ID]);       // 42
console.log(user.name);      // "Alice"

// Symbol keys are hidden from normal enumeration:
console.log(Object.keys(user));       // ["name"] — no symbols
console.log(JSON.stringify(user));    // {"name":"Alice"} — symbols dropped

// You need the actual Symbol reference to access it:
// user["secret"]  → undefined (that's a string key, not the Symbol)

The main uses of Symbols

// 1. Unique constants (no collision with other code):
const STATUS_PENDING  = Symbol("pending");
const STATUS_DONE     = Symbol("done");
const STATUS_FAILED   = Symbol("failed");

function process(task) {
  task.status = STATUS_PENDING;
  // ... do work ...
  task.status = STATUS_DONE;
}

// 2. Adding metadata to objects you don't own:
const META = Symbol("meta");
const thirdPartyObject = { data: [1, 2, 3] };
thirdPartyObject[META] = { addedAt: Date.now() };  // won't clash with any existing key

// 3. The global registry — share a Symbol across modules:
const shared1 = Symbol.for("app.user.id");
const shared2 = Symbol.for("app.user.id");
console.log(shared1 === shared2);  // true — same symbol from registry
Try It Yourself

Official Sources

The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.