What are Symbols for?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
A Symbol is a primitive whose only property is that it is unique. Two symbols are never equal, even with the same description:
Symbol("id") === Symbol("id"); // false
That uniqueness is the whole point: a symbol used as a property key cannot collide with any other key, now or in future.
Avoiding collisions
const cache = Symbol("cache");
function decorate(obj) {
obj[cache] = expensiveThing(); // cannot clash with anything the object owns
}
This matters when you attach data to objects you do not control — a library adding bookkeeping to user objects, for example. A string key like _cache might overwrite something real.
Hidden from normal iteration
Symbol keys are skipped by for...in, Object.keys, and JSON.stringify:
const o = { visible: 1, [Symbol("hidden")]: 2 };
Object.keys(o); // ["visible"]
JSON.stringify(o); // {"visible":1}
Object.getOwnPropertySymbols(o); // [Symbol(hidden)] — still reachable
This is not privacy — anyone can list them with getOwnPropertySymbols. Use #fields for real privacy. Symbols hide metadata from serialisation, not from determined code.
Well-known symbols hook into the language
The most useful role. These let your object participate in built-in behaviour:
class Range {
*[Symbol.iterator]() { yield 1; yield 2; } // now works with for...of
}
class Temp {
[Symbol.toPrimitive](hint) { return hint === "number" ? 42 : "warm"; }
}
Symbol.iterator, Symbol.asyncIterator, Symbol.toStringTag and Symbol.hasInstance are the ones you will meet.
One more variant
Symbol.for("key") looks up a global registry and returns the same symbol across realms — the opposite of the default behaviour, useful when two independent scripts must agree on a key.
