What is Symbol?
What Symbol is
Symbolis a unique and immutable value that can be used as an object property key.
Every Symbol is unique, even if it has the same description.
Example:
const id1 = Symbol('id');
const id2 = Symbol('id');
console.log(id1 === id2); // falseDespite the same 'id' description, the symbols are not equal.
Every Symbol is a unique identifier.
Why Symbol is needed
Before symbols existed, object property keys could only be:
- strings (
'name','age');
Sometimes you need to add a "hidden" property to an object,
so it does not interfere with the rest of the code (for example, libraries).
This is where Symbol helps.
Example: a "hidden" property
const id = Symbol('id');
const user = {
name: 'Alex',
[id]: 123, // a symbol as the key
};
console.log(user);
// { name: 'Alex', [Symbol(id)]: 123 }
console.log(user[id]); // 123
console.log(Object.keys(user)); // ['name'] - the symbol is not visibleSymbol keys do not appear in for...in, Object.keys(), and they do not interfere with other properties.
This is convenient for internal data or "private" properties.
A symbol as a key - example
const TOKEN = Symbol('token');
const session = {
user: 'Tim',
[TOKEN]: 'secret-token-123',
};
console.log(session.user); // Tim
console.log(session[TOKEN]); // secret-token-123
console.log(Object.keys(session)); // ['user']So the [TOKEN] property exists, but it is "invisible" to most operations.
Getting all the symbols of an object
To get symbol properties:
const symbols = Object.getOwnPropertySymbols(session);
console.log(symbols); // [Symbol(token)]
console.log(session[symbols[0]]); // secret-token-123Symbols do not convert to strings
const sym = Symbol('id');
console.log('My symbol: ' + sym); // TypeErrorTo print a symbol as a string:
console.log(sym.toString()); // Symbol(id)Global symbols (Symbol.for)
Sometimes you need the same Symbol to be used in different parts of a program.
There is a global symbol registry for that:
const a = Symbol.for('shared');
const b = Symbol.for('shared');
console.log(a === b); // trueSymbol.for(key) creates (or returns an already existing) global symbol.
You can get it by name through Symbol.keyFor():
console.log(Symbol.keyFor(a)); // 'shared'Well-known symbols
JS defines several built-in symbols that let you override the behavior of objects. For example:
| Symbol | What it is used for |
|---|---|
Symbol.iterator | Lets an object be iterable (for...of) |
Symbol.toPrimitive | Controls the conversion of an object to a primitive |
Symbol.toStringTag | Sets the name used by Object.prototype.toString |
Symbol.hasInstance | Defines the behavior of the instanceof operator |
Symbol.species | Controls the creation of subclasses |
Symbol.asyncIterator | For asynchronous iterators |
Example: Symbol.iterator
const numbers = {
data: [1, 2, 3],
[Symbol.iterator]() {
let i = 0;
const arr = this.data;
return {
next() {
return i < arr.length
? { value: arr[i++], done: false }
: { done: true };
}
};
}
};
for (const n of numbers) {
console.log(n); // 1, 2, 3
}Thanks to Symbol.iterator, the object became "iterable".
Comparing Symbol with other types
| Type | Can be an object key | Uniqueness | Appears in for...in |
|---|---|---|---|
string | Yes | No | Yes |
number | No (converted to a string) | No | - |
Symbol | Yes | Yes | No |
Practical use
Use Symbol when:
- you need to create a unique identifier that will not collide with other properties;
- you need to add a "private" property to an object or class;
- you need to customize the behavior of objects using well-known symbols (
Symbol.iterator,Symbol.toPrimitive, and so on).
Quick summary
| What | Description |
|---|---|
| Type | A primitive (symbol) |
| Main feature | Uniqueness |
| Creation | Symbol('description') |
| Object keys | Can be used as a key (unique and hidden) |
| Global symbols | Symbol.for() / Symbol.keyFor() |
| Well-known symbols | Let you override JS's behavior |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.