This chapter follows Strings and template literals.
Symbol is the seventh primitive type. Each Symbol() call creates a value that is not equal to any other symbol, even when the optional description string matches. That makes symbols useful for keys that must stay private to a module or library without hiding them from the language — only from accidental name clashes.
Creating symbols
const a = Symbol("id");const b = Symbol("id");
a === b; // false — description is not part of identitytypeof a; // "symbol"Symbols are not valid JSON keys in the usual serialization story; JSON.stringify omits symbol-keyed properties unless you add a replacer.
Symbols as property keys
Use bracket notation to define and read symbol properties:
const cacheKey = Symbol("cache");const obj = { name: "layer", [cacheKey]: new Map(),};
obj[cacheKey]; // MapObject.keys(obj); // ["name"] — symbol keys are non-enumerable in ordinary enumerationObject.getOwnPropertySymbols returns symbol keys. for...in still skips them, which is why symbols work well for metadata that should not appear in generic logging loops.
Global symbol registry
Symbol.for(key) looks up or creates a symbol in the cross-realm registry. Symbol.keyFor(sym) returns the key for registered symbols only.
const shared = Symbol.for("app.config");const same = Symbol.for("app.config");shared === same; // trueUse the registry when multiple bundles must agree on one well-known symbol. Use Symbol() when the key should stay unique to one module.
Well-known symbols
The spec defines built-in symbols on Symbol, such as Symbol.iterator, Symbol.toStringTag, and Symbol.hasInstance. Engines and libraries read these to customize behavior:
class Range { *[Symbol.iterator]() { yield* [1, 2, 3]; }}
[...new Range()]; // [1, 2, 3]You rarely implement all of them. Symbol.iterator for iterables and occasional Symbol.toStringTag for debugging are the ones application code touches most.
Symbols versus strings and TypeScript
String keys participate in JSON, object spread defaults, and most typing tools. Symbol keys are for internal slots and protocols. In TypeScript, symbol keys need explicit typing on the object shape; see Symbols in TypeScript.
Symbols do not coerce to strings implicitly. sym + "" throws. Use String(sym) or sym.description when you need text.
Next: JavaScript Fails.