Symbols are a primitive data type introduced in ES6. They are unique and immutable values, mainly used as identifiers for object properties to avoid name collisions and create properties that are not accidentally overwritten.
Think of a symbol as a special kind of key that is guaranteed to be unique, even if it has the same description as another symbol.
number, string, and boolean.Symbol() is only for debugging/logging.Symbol.iterator) let you customize built-in behavior.for...in.To create a symbol, you call the Symbol() function:
Syntax
let mySymbol = Symbol(descriptionOptional);
Symbol() returns a new, unique symbol.sym.description.When used as object keys, symbols help create properties that will not clash with other keys, including those from libraries or other parts of your code.
Even if two symbols share the same description, they are always different values.
let sym1 = Symbol('description');
let sym2 = Symbol('description');
console.log(sym1 === sym2);
false (symbols are unique)
The description is useful in logs and debugging tools, but it does not affect equality.
let sym = Symbol('id');
console.log(sym.description);
"id"
Symbols work great as “hidden” or non-colliding keys on objects. They do not appear in normal key enumeration but can still be accessed directly with the symbol.
let id = Symbol('id');
let user = {
name: 'Alice',
[id]: 12345
};
console.log(user[id]);
12345
console.log(Object.keys(user));
["name"]
console.log(Object.getOwnPropertySymbols(user));
[Symbol(id)]
JavaScript defines several built-in symbols (well-known symbols) that let you customize how objects behave with certain language features.
Symbol.iterator – Makes objects iterable (for for...of loops).Symbol.toStringTag – Customizes Object.prototype.toString output.Symbol.hasInstance – Customizes instanceof behavior.
let obj = {
[Symbol.toStringTag]: 'CustomObject'
};
console.log(Object.prototype.toString.call(obj));
[object CustomObject]
sym1 === sym2 prints false because each symbol is unique.sym.description prints the string passed to Symbol('id'), i.e., "id".user[id] prints 12345 (the hidden property value).Object.keys(user) prints ["name"], not including the symbol key.Object.getOwnPropertySymbols(user) prints something like [Symbol(id)].Object.prototype.toString.call(obj) prints [object CustomObject] instead of the default.These outputs demonstrate that symbols provide unique, non-enumerable keys and can also customize how objects interact with core language features.
for...in or Object.keys(); use Object.getOwnPropertySymbols() when needed.Symbol.iterator and Symbol.toStringTag to customize interaction with built-in JavaScript features.===. Observe that they are not equal.Object.keys(), but it does appear in Object.getOwnPropertySymbols().Symbol.iterator so you can iterate over it using a for...of loop.Symbol.toStringTag on an object and check how Object.prototype.toString.call() output changes.