The JavaScript Symbol object
A Symbol is a primitive that produces a guaranteed-unique value. Symbol("id") creates one; every call makes a brand-new symbol, even with the same description, so two symbols are never equal. Their main use is as object keys that can't collide with any other key, and as the well-known symbols (like Symbol.iterator) that customize built-in behavior.
Overview
Symbol is the newest primitive type, and it has one defining property: every symbol is unique. Symbol("id") creates a symbol, and calling it again with the exact same description gives a different symbol — Symbol("id") === Symbol("id") is false. The string you pass is just a label for debugging, not an identity. You call Symbol() directly (never with new).
That uniqueness makes symbols ideal as object keys that are guaranteed not to clash with any existing or future key. A library can add a symbol-keyed property to an object knowing it can't accidentally overwrite the user's data, and symbol keys don't show up in normal iteration (for...in, Object.keys()), keeping them out of the way.
The place you'll most often meet symbols is the well-known symbols — built-in symbols that hook into language behavior. Symbol.iterator is the big one: defining it on an object makes that object iterable, so for...of and the spread operator work on it. For day-to-day app code you may rarely create your own symbols, but understanding them explains how a lot of JavaScript's extensibility works.
Syntax
const id = Symbol("id"); // unique symbol
Symbol("id") === Symbol("id"); // false - always unique
const obj = {};
obj[id] = 123; // collision-proof key
// well-known symbol
obj[Symbol.iterator] = function* () { /* makes obj iterable */ };
Example
<pre id="out" style="font:15px ui-monospace,monospace"></pre>
<script>
const a = Symbol('id');
const b = Symbol('id');
const user = { name: 'Ada' };
user[a] = 42; // hidden, collision-proof key
document.getElementById('out').textContent =
'a === b? ' + (a === b) + '\n' +
'visible keys: ' + Object.keys(user).join(', ');
// a === b? false / visible keys: name
</script>
Best practices
- Call
Symbol()directly — nevernew Symbol(), which throws. - Use symbols for object keys that must not collide with any other key.
- Pass a description (
Symbol("label")) for easier debugging — it doesn't affect uniqueness. - Reach for well-known symbols like
Symbol.iteratorto customize built-in behavior.
Frequently asked questions
What is a Symbol in JavaScript?
Why is Symbol("x") === Symbol("x") false?
What are symbols used for?
Symbol.iterator) that hook into language features such as iteration.How do I make an object iterable?
[Symbol.iterator] method on it that returns an iterator — then for...of and spread will work on it.