Photo by chansu shin on Unsplash

On this page

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 identity
typeof 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]; // Map
Object.keys(obj); // ["name"] — symbol keys are non-enumerable in ordinary enumeration

Object.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; // true

Use 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.

Search articles

Type a word to search published articles.

Open the search page