What if two parts of an app both use the string 'right' for different flags? A tooltip expecting a position could silently accept an unrelated answer flag. A symbol avoids that collision: it is a JavaScript primitive, and each call to Symbol() creates a value unequal to every other newly created symbol. section 13.1 section 13.0
Same description, different value
const right = Symbol('right'); const alsoRight = Symbol('right'); right === alsoRight; // false right === right; // true The description does not determine identity. Reuse the same symbol when two places must compare equal; calling Symbol('right') again creates a different one. section 13.1
Symbols have three useful roles:
- Unique symbols make constants such as position flags resistant to accidental naming collisions. section 13.1
- Global symbols are retrieved from a shared registry with Symbol.for(), so code can agree on a symbol used as a custom-object hook. section 13.6 section 13.2
- Well-known symbols are built-in hooks. For example, an object can define [Symbol.toPrimitive](hint) to choose a value when JavaScript coerces it to a primitive. section 13.4
A symbol can also name an object property. Use a computed property name, such as { [Symbol('internals')]: value }. That property stays out of for...in, JSON.stringify(), and Object.getOwnPropertyNames(), but it is not secure private storage: Object.getOwnPropertySymbols() can reveal its key. Think of it as a less-visible API surface. section 13.2
A symbol as a lock key
function lock(secret) { const key = Symbol('key'); return { key, unlock(keyUsed) { return keyUsed === key ? secret : '*'.repeat(String(secret).length); } }; } const { key, unlock } = lock(42); unlock(key); // 42 unlock(Symbol('key')); // '**' The second call fails because a matching description does not recreate the original key. Try making two locks and swapping their keys. section 14.1
Call Symbol() without new; new Symbol() throws. Avoid implicit conversion to strings or numbers, which also throws. For a coercion hook, the hint can be 'string', 'number', or 'default'; calling an object's toString() directly does not invoke that hook. section 13.5 section 13.4




