References

Beginner-friendly references for web development, with live, editable examples.

The JavaScript Symbol object

Object JavaScript All modern browsers Updated
Quick answer

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

Live 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 — never new 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.iterator to customize built-in behavior.

Frequently asked questions

What is a Symbol in JavaScript?
A primitive that creates a guaranteed-unique value, most often used as a collision-proof object key.
Why is Symbol("x") === Symbol("x") false?
Because every symbol is unique. The description is just a label, not an identity, so two symbols are never equal.
What are symbols used for?
Unique object keys that won't clash, and the well-known symbols (like Symbol.iterator) that hook into language features such as iteration.
How do I make an object iterable?
Define a [Symbol.iterator] method on it that returns an iterator — then for...of and spread will work on it.