liveBook · Manning

Symbol

As explained in Get Programming with JavaScript Next: New features of ECMAScript 2015, 2016, and beyond

A symbol value that is guaranteed not to be equal to any other symbol value.

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

How Get Programming with JavaScript Next: New features of ECMAScript 2015, 2016, and beyond covers it

How deep it goes
Works through identity, property visibility, coercion hooks, and errors, while deferring most well-known symbols.
Examples
Uses tooltip flags, coercion with Symbol.toPrimitive, and a lock-and-key exercise.
What it assumes
Assumes familiarity with JavaScript objects and functions while introducing symbols as a new primitive.
What you can do after
Build it from scratch: create collision-free flags or a lock whose key matches only its original symbol.
How it connects
Connects symbols to object property keys, computed property names, coercion, and the global symbol registry.

Also explained in

Compare how 5 books explain symbol →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Get Programming with JavaScript Next: New features of ECMAScript 2015, 2016, and beyond. The section links point to the parts of the book it draws on.