Skip to content

Step 1 of 7 · Reading · ~3 min

Learn

The Runtime

Symbols and Well-Known Symbols

A symbol is a primitive value that is guaranteed unique. That makes it a property key nobody else can collide with, and it is also how the language lets your objects plug into built-in behaviour such as for...of, +, instanceof and String(x). By the end you can make a class control how it converts to numbers and strings.

Unique values, used as keys

Every call to Symbol() makes a new value; the optional description is only a label for debugging.

javascript

That hiding is a convenience, not privacy: anyone with the object can list its symbols. Use #private fields when you need real encapsulation.

Symbol.for('app.id') instead asks a process-wide registry: the same string always returns the same symbol, in every module. Symbol.keyFor(sym) reads the string back, and gives undefined for a symbol made with plain Symbol().

A symbol never converts to a string implicitly: Symbol() + '' throws a TypeError. Use String(sym) or .description.

Well-known symbols: hooks into the language

The Symbol constructor carries a set of ready-made symbols. Defining a method under one of them changes how a built-in operation treats your object:

SymbolOperation it customises
Symbol.iteratorfor...of, spread, destructuring (you built this in Intermediate)
Symbol.asyncIteratorfor await...of
Symbol.hasInstancex instanceof C (a static method on C)
Symbol.toStringTagthe tag in Object.prototype.toString.call(x)
Symbol.toPrimitiveconverting the object to a number or string
javascript

Symbol.toPrimitive and its three hints

When an object meets an operator that needs a primitive, the engine calls its [Symbol.toPrimitive](hint) method with a hint saying what the operation wants. Without one, it falls back to valueOf() and toString(), which is where [object Object] and NaN come from.

The hint is...when the object is used in
'number'+x, x - y, x * y, x < y, x > y, Math.max(x)
'string'`${x}`, String(x), obj[x] as a property key
'default'x + y, x + '', x == 'text'
javascript

The 'default' hint is the one that surprises people. If your method returns the number for it, t + '' becomes '125' and == against text stops working. Decide which form default should take and return that; the built-in Date returns its string form there.

Common mistakes

  • Writing [id]: value as id: value. Without the brackets the key is the string 'id'.
  • Assuming Object.keys or JSON.stringify will show a symbol-keyed property. Neither does.
  • Handling only 'number' and 'string' in toPrimitive. + and == pass 'default', so it needs a deliberate answer.

Your exercise

You will give a Version class its own conversions, so that sorting, comparison and printing all work on the objects directly. The usual slip is the 'default' hint: the starter prints the newest version through +, and a sort by a - b needs numbers while printing needs text.

Up nextBigInt and Numeric Edge CasesNumbers and Performance

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…