This guide teaches you about the JavaScript Symbol data type. You will learn what a Symbol is and how it is different from other data types. We will explore how Symbols help create truly unique values. You will also see why this uniqueness is very useful in your coding projects.
Symbol
Symbol
JavaScript has several types of data. A Symbol is a special and new kind of data type. It was added to JavaScript to solve a common programming problem. This problem is making sure that different parts of your code do not accidentally use the same name for different things.
What is a Symbol?
A Symbol is a unique and immutable primitive value in JavaScript. "Unique" means no two Symbols are ever exactly the same. "Immutable" means once you create a Symbol, it can never be changed.
Always Unique
Every Symbol you create is guaranteed to be different from all other Symbols, even if they look similar.
Prevents Conflicts
Symbols help avoid naming issues when you add properties to objects, ensuring names do not clash.
Well-known Symbols
JavaScript uses special Symbols internally to change how built-in features like loops or type conversions work.
Object Keys
You can use Symbols as unique keys for object properties, which makes them hidden from common iteration methods.
Getting Started with Symbols
Getting Started with Symbols
Creating a Symbol is very easy. You just call the Symbol() function. You can also give it a description. This description helps you understand what the Symbol is for when you are debugging your code. The description does not affect the Symbol's uniqueness.
1const myUniqueId = Symbol('This is my unique identifier'); // Create a new Symbol with a description2const anotherSymbol = Symbol(); // Create another Symbol without a description34console.log(typeof myUniqueId); // Output: "symbol" - shows its data type5console.log(myUniqueId.description); // Output: "This is my unique identifier" - shows the description
Do Not Use 'new Symbol()'
You should never use the new keyword with Symbol(). For example, new Symbol() will cause an error. Symbols are not constructor functions like new Date() or new Object(). Just call Symbol() directly.
How Symbols Work: Uniqueness
How Symbols Work: Uniqueness
The most important feature of Symbols is their uniqueness. Every time you call Symbol(), you get a brand new value. This new value is different from every other Symbol, even if they have the same description. This is very important for preventing problems in larger programs where many parts of the code might try to use the same names.
1const symbolA = Symbol('key'); // Create a Symbol with description 'key'2const symbolB = Symbol('key'); // Create another Symbol with the exact same description 'key'34console.log(symbolA === symbolB); // Output: false - they are not the same, they are unique56const symbolC = symbolA; // Assign symbolA to symbolC7console.log(symbolA === symbolC); // Output: true - symbolC now refers to the exact same Symbol as symbolA
const user = {};user.id = 123; // This 'id' is a string key// Imagine another part of the code also uses 'id'user.id = 'admin'; // This will overwrite the previous 'id'console.log(user.id); // Output: "admin"
const user = {};const userIdSymbol = Symbol('userId'); // Create a unique Symbol for user IDconst adminIdSymbol = Symbol('adminId'); // Create another unique Symbol for admin IDuser[userIdSymbol] = 123; // Use Symbol as a keyuser[adminIdSymbol] = 'admin'; // Use another Symbol as a keyconsole.log(user[userIdSymbol]); // Output: 123 (original value is safe)console.log(user[adminIdSymbol]); // Output: "admin" (no clash occurred)
Using Symbols in Objects
Using Symbols in Objects
One of the most common ways to use Symbols is as keys for properties in objects. Normally, object keys are strings. But if you use Symbols as keys, they behave differently. Symbol properties are not easily accessible by common methods like for...in loops or Object.keys(). This makes them useful for adding special, non-public properties to an object.
const myObject = {name: 'Alice',age: 30};for (let key in myObject) {console.log(key + ': ' + myObject[key]);}// Output:// name: Alice// age: 30
const myObject = {name: 'Bob'};const secretKey = Symbol('secret');myObject[secretKey] = 'hidden value';for (let key in myObject) {console.log(key + ': ' + myObject[key]);}// Output:// name: Bob// (secretKey is not shown by for...in)console.log(myObject[secretKey]); // Output: "hidden value" (still accessible if you know the Symbol)
const myObject = {name: 'Alice',age: 30};for (let key in myObject) {console.log(key + ': ' + myObject[key]);}// Output:// name: Alice// age: 30
const myObject = {name: 'Bob'};const secretKey = Symbol('secret');myObject[secretKey] = 'hidden value';for (let key in myObject) {console.log(key + ': ' + myObject[key]);}// Output:// name: Bob// (secretKey is not shown by for...in)console.log(myObject[secretKey]); // Output: "hidden value" (still accessible if you know the Symbol)
When to Use Symbol Keys
Use Symbol keys when you want to add properties to an object that should not be accidentally overwritten. They are also good for properties that you do not want to appear when iterating over an object's keys. This helps create a kind of 'private' property without being truly private.
Practical Uses of Symbols
Practical Uses of Symbols
Besides unique object keys, Symbols have other practical uses. JavaScript also has 'well-known Symbols' that are built-in. These Symbols allow you to customize how your objects behave with certain JavaScript operations. For example, Symbol.iterator lets you make an object iterable, like an array.
Create a Shared Symbol (Global Registry)
Sometimes, you need to share the same Symbol value across different files or parts of your code. For this, you use Symbol.for(). It checks if a Symbol with that key already exists in a global registry. If it does, it returns the existing Symbol. Otherwise, it creates a new one and adds it to the registry.
1const globalSymbol1 = Symbol.for('myApp.config');2console.log(globalSymbol1.description); // Output: "myApp.config"
Retrieve the Same Shared Symbol
If another part of your code calls Symbol.for() with the exact same key, it will get the same Symbol instance. This means globalSymbol1 === globalSymbol2 will be true. This is different from Symbol() which always creates a new, unique Symbol.
1const globalSymbol2 = Symbol.for('myApp.config');2console.log(globalSymbol1 === globalSymbol2); // Output: true
Get the Key of a Shared Symbol
You can get the string key of a Symbol from the global registry using Symbol.keyFor(). This only works for Symbols created with Symbol.for(). It will return undefined for Symbols created with plain Symbol().
1const key = Symbol.keyFor(globalSymbol1);2console.log(key); // Output: "myApp.config"34const plainSymbol = Symbol('local');5console.log(Symbol.keyFor(plainSymbol)); // Output: undefined
Symbol Properties and Iteration
Symbol properties are not included when you use for...in loops, Object.keys(), Object.values(), or Object.entries(). This is by design. If you need to access Symbol properties, you must use Object.getOwnPropertySymbols(obj). This method returns an array of all Symbol properties on an object.
Symbol Reference and FAQs
Symbol Reference and FAQs
| Feature | `Symbol()` | `Symbol.for()` | Why it matters |
|---|---|---|---|
| Uniqueness | Always creates a new, unique Symbol. | Returns an existing Symbol from global registry or creates a new one if not found. | Controls whether you need a truly unique identifier or a shared one. |
| Global Scope | Local to where it's created. | Stored in a global Symbol registry, accessible everywhere. | Allows Symbols to be shared across different parts of a large application. |
| Getting Key | `Symbol.keyFor()` returns `undefined`. | `Symbol.keyFor()` returns the string key. | Helps in debugging and managing shared Symbols. |
| Use Case | Private object keys, unique identifiers. | Shared constants, extending third-party objects safely. | Choosing the right tool for specific naming conflict scenarios. |
Test Your Knowledge
Test Your Knowledge
What is the primary characteristic of a JavaScript Symbol?
How do you create a new, non-globally shared Symbol?
What will be the output of Symbol('test') === Symbol('test')?
Which method allows you to retrieve a Symbol from a global registry, ensuring you get the same Symbol instance across your application?
Quick Reference
Quick Reference
- 1Symbol — A new primitive data type in JavaScript, introduced in ES6.
- 2Uniqueness — Every Symbol created with
Symbol()is guaranteed to be unique, even with identical descriptions. - 3Immutability — Symbols cannot be changed once they are created.
- 4Creation — Use
Symbol('description')to create a Symbol; never usenew Symbol(). - 5Object Keys — Symbols can be used as keys for object properties, preventing naming collisions.
- 6Hidden Properties — Symbol properties are not enumerated by
for...in,Object.keys(),Object.values(), orObject.entries(). - 7Accessing Symbol Keys — Use
Object.getOwnPropertySymbols(obj)to get an array of an object's Symbol properties. - 8Global Symbols —
Symbol.for('key')creates or retrieves a Symbol from a global registry, allowing shared Symbols across codebases. - 9Retrieving Key —
Symbol.keyFor(symbol)returns the string key for a global Symbol, orundefinedfor local Symbols. - 10Well-known Symbols — Built-in Symbols like
Symbol.iteratorare used by JavaScript to customize internal object behavior.
JavaScript Objects
Understand how objects work in JavaScript, as Symbols are often used as object property keys.
Data Types
Explore other primitive and non-primitive data types in JavaScript to build a stronger foundation.
Iterators and Generators
Learn about iterators, which often use the Symbol.iterator well-known Symbol for custom iteration.
Encapsulation
Dive into concepts of data hiding and encapsulation in JavaScript, where Symbols play a role in 'soft privacy'.
Congratulations!
You've successfully learned about the JavaScript Symbol data type! You now understand its core principle of uniqueness, how to create Symbols, and their practical uses in preventing naming conflicts and customizing object behavior. Keep practicing to master this powerful feature!
Try it in the Javascript Compiler
Run and experiment with Javascript code right in your browser — no setup needed.