Skip to content

symbol

In JavaScript, symbol is a primitive type whose values are unique, immutable identifiers, most often used as property keys that can’t collide with any other key. It’s one of JavaScript’s primitive types, distinct from the Symbol wrapper object, whose prototype supplies its methods:

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

> id
Symbol(id)
> typeof id
'symbol'

Symbols are immutable and compare by identity. Every call to Symbol() returns a new value, so two symbols with the same description are never equal under === or Object.is(). The type was added in ES2015.

symbol Values and typeof

The symbol type has no literal syntax. Calling Symbol() as a function creates a value, and its optional argument becomes a read-only .description that only helps with debugging:

Language: JavaScript
> Symbol("id") === Symbol("id")
false

> Symbol("id").description
'id'
> Symbol().description
undefined

> typeof Symbol.iterator
'symbol'

Symbol.for() is the exception to uniqueness. It looks up a key in a global symbol registry and returns the same symbol for the same key across every realm, including other iframes, and Symbol.keyFor() returns the key of a registered symbol:

Language: JavaScript
> Symbol.for("app.id") === Symbol.for("app.id")
true

> Symbol.keyFor(Symbol.for("app.id"))
'app.id'
> Symbol.keyFor(Symbol("app.id"))
undefined

Symbols as Property Keys

A symbol used as a computed key creates a property that string-based tools skip. Object.keys(), for...in, and JSON.stringify() ignore symbol keys, while Object.getOwnPropertySymbols() and Reflect.ownKeys() list them:

Language: JavaScript
> const secret = Symbol("secret");
undefined
> const user = { name: "Ada", [secret]: 42 };
undefined

> Object.keys(user)
[ 'name' ]
> JSON.stringify(user)
'{"name":"Ada"}'

> Object.getOwnPropertySymbols(user)
[ Symbol(secret) ]
> user[secret]
42

Symbol keys are skipped by these string-based tools, but they aren’t private. Any code that holds a reference to the symbol, or calls Object.getOwnPropertySymbols(), can read the property.

ECMAScript also defines well-known symbols, static properties of Symbol that let objects hook into language behavior. A [Symbol.iterator]() method makes an object iterable, so for...of and spread syntax work on it:

Language: JavaScript
> const countdown = { *[Symbol.iterator]() { yield 3; yield 2; yield 1; } };
undefined
> [...countdown]
[ 3, 2, 1 ]

Other well-known symbols include Symbol.toPrimitive, Symbol.hasInstance, and Symbol.asyncIterator.

Converting to symbol

No conversion creates a symbol from another type. Passing a value to Symbol() only sets the description, and the result is a new symbol each time. Going the other way, String() converts a symbol to a string explicitly, and Boolean() returns true for every symbol, which makes symbols truthy:

Language: JavaScript
> String(Symbol("id"))
'Symbol(id)'
> Boolean(Symbol())
true

Common symbol Gotchas

Implicit type coercion to a string throws a TypeError, so string concatenation and template literals fail on a symbol:

Language: JavaScript
> "" + Symbol("id")
Uncaught TypeError: Cannot convert a Symbol value to a string

> `${Symbol("id")}`
Uncaught TypeError: Cannot convert a Symbol value to a string

Numeric conversion throws too, including the unary + operator:

Language: JavaScript
> +Symbol("id")
Uncaught TypeError: Cannot convert a Symbol value to a number

Copying an object with JSON.stringify() and JSON.parse() drops its symbol-keyed properties without warning, while spread syntax and Object.assign() copy them:

Language: JavaScript
> const tag = Symbol("tag");
undefined
> const item = { [tag]: "featured" };
undefined

> JSON.parse(JSON.stringify(item))[tag]
undefined

> ({ ...item })[tag]
'featured'

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. 4, 2026