What are Symbols in JavaScript?
A Symbol is a primitive that creates a guaranteed-unique, immutable value, mainly used as an object key that won't clash with others.
Uniqueness — every Symbol() is unique, even with the same description.
Hidden-ish keys — symbol keys are skipped by for...in, Object.keys, and JSON.stringify.
Well-known symbols — special ones like Symbol.iterator customise built-in behaviour.
Common use: add metadata or special keys to objects without risking name collisions.
// Creating symbols
const id = Symbol('id');
const id2 = Symbol('id');
console.log(id === id2); // false — always unique!
// As object property keys
const user = {
name: 'John',
[id]: 12345 // Symbol-keyed property
};
console.log(user[id]); // 12345
console.log(Object.keys(user)); // ['name'] — symbol hidden!
console.log(JSON.stringify(user)); // '{"name":"John"}' — symbol excluded!
// Well-known symbols
class Range {
constructor(start, end) { this.start = start; this.end = end; }
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
return {
next() {
return current <= end
? { value: current++, done: false }
: { done: true };
}
};
}
}
for (const n of new Range(1, 5)) console.log(n); // 1,2,3,4,5
// Symbol.for — global registry (shared across realms)
const s1 = Symbol.for('app.id');
const s2 = Symbol.for('app.id');
console.log(s1 === s2); // true — same registry keySymbol('id') creates unique values (id !== id2). Symbol-keyed properties are hidden from Object.keys and JSON.stringify.
Symbol.iterator enables custom objects to work with for...of. Symbol.for uses a global registry where the same key returns the same symbol (useful for cross-module communication).
Know two uses: unique property keys (no collisions) and well-known symbols (Symbol.iterator for custom iterables). Symbol properties being hidden from Object.keys/JSON is important.
Symbol.for vs Symbol() — registry vs always-unique.