Skip to content

Symbol

The Symbol global object is the factory function that creates symbol values, and its static properties hold the well-known symbols that let objects customize built-in language behavior. Each value it returns is a symbol primitive, and Symbol.prototype supplies the methods those primitives call:

Language: JavaScript
> const sessionKey = Symbol("session");
undefined

> sessionKey.description
'session'
> sessionKey.toString()
'Symbol(session)'

Symbol is an ECMAScript built-in added in ES2015. It’s Baseline Widely available, so it runs in every current browser and JavaScript runtime.

Syntax

The Symbol function takes one optional description:

Language: JavaScript Syntax
Symbol([<description>])
Parameter Description
description An optional value that’s converted to a string and stored as the symbol’s .description. It defaults to undefined

The call returns a new, unique symbol primitive. The new keyword is forbidden, so new Symbol() throws a TypeError.

Key Static Methods and Properties

Member Kind Description
Symbol.for() Static method Returns the symbol stored under a string key in the global symbol registry, creating it on first use
Symbol.keyFor() Static method Returns the registry key of a registered symbol, or undefined for any other symbol
Symbol.iterator Static property Names the method that makes an object iterable with for...of and spread syntax
Symbol.asyncIterator Static property Names the method that makes an object iterable with for await...of
Symbol.toPrimitive Static property Names the method that converts an object to a primitive value
Symbol.toStringTag Static property Names the property that Object.prototype.toString() reads for an object’s tag
Symbol.hasInstance Static property Names the method that customizes instanceof checks
Symbol.dispose Static property Names the cleanup method that using declarations and DisposableStack call. Stage 4 in 2026, expected in ES2027, and Baseline Limited availability
Symbol.asyncDispose Static property Names the async cleanup method that await using calls. Stage 4 in 2026, expected in ES2027, and Baseline Limited availability

Other well-known symbols customize regular expressions and arrays: Symbol.match, Symbol.matchAll, Symbol.replace, Symbol.search, Symbol.split, Symbol.species, Symbol.isConcatSpreadable, and Symbol.unscopables.

Key Instance Methods and Properties

Member Kind Description
.description Instance property Holds the description passed to Symbol(), or undefined when there was none
.toString() Instance method Returns a string in the form "Symbol(description)"
.valueOf() Instance method Returns the symbol primitive itself

Examples

A Money class needs to behave like a number in arithmetic and like a formatted label in a template literal. A [Symbol.toPrimitive]() method receives a hint that tells it which form the operation wants:

Language: JavaScript
> class Money {
…   constructor(cents) {
…     this.cents = cents;
…   }
…   [Symbol.toPrimitive](hint) {
…     if (hint === "string") {
…       return `$${(this.cents / 100).toFixed(2)}`;
…     }
…     return this.cents;
…   }
… }
undefined
> const price = new Money(1999);
undefined

> price + 1
2000
> `Total: ${price}`
'Total: $19.99'

A paginated API client can expose its pages as an async iterable. Defining [Symbol.asyncIterator]() as an async generator method lets for await...of consume the pages one at a time:

Language: JavaScript
> const feed = {
…   async *[Symbol.asyncIterator]() {
…     yield ["post-1", "post-2"];
…     yield ["post-3"];
…   },
… };
undefined

> for await (const page of feed) console.log(page);
[ 'post-1', 'post-2' ]
[ 'post-3' ]
undefined

A logging helper prints a type label for every value it receives. Setting [Symbol.toStringTag] on a class gives its instances a readable tag instead of the generic Object:

Language: JavaScript
> class Connection {
…   get [Symbol.toStringTag]() {
…     return "Connection";
…   }
… }
undefined

> Object.prototype.toString.call(new Connection())
'[object Connection]'

Common Gotchas

Calling Symbol with new throws, because symbols are primitives and the function isn’t a constructor:

Language: JavaScript
> new Symbol("id")
Uncaught TypeError: Symbol is not a constructor
    at new Symbol (<anonymous>)

Registered symbols from Symbol.for() can’t be keys in a WeakMap, because the registry keeps them alive forever. A symbol from Symbol() works:

Language: JavaScript
> const cache = new WeakMap();
undefined

> cache.set(Symbol.for("user"), "Ada")
Uncaught TypeError: Invalid value used as weak map key
    at WeakMap.set (<anonymous>)

> cache.set(Symbol("user"), "Ada").constructor.name
'WeakMap'

Non-registered symbols became valid weak keys in ES2023.

Have a question about this? Mentor AI can show you examples, compare related terms, and point you to tutorials.


By Leodanis Pozo Ramos • Updated Nov. 7, 2026