What are `Symbol`s used for in JavaScript?
TL;DR
Symbol
s in JavaScript are a new primitive data type introduced in ES6 (ECMAScript 2015). They are unique and immutable identifiers that is primarily for object property keys to avoid name collisions. These values can be created using Symbol(...)
function, and each Symbol
value is guaranteed to be unique, even if they have the same key/description. Symbol
properties are not enumerable in for...in
loops or Object.keys()
, making them suitable for creating private/internal object state.
let sym1 = Symbol();let sym2 = Symbol('myKey');console.log(typeof sym1); // "symbol"console.log(sym1 === sym2); // false, because each symbol is uniquelet obj = {};let sym = Symbol('uniqueKey');obj[sym] = 'value';console.log(obj[sym]); // "value"
Note: The Symbol()
function must be called without the new
keyword. It is not exactly a constructor because it can only be called as a function instead of with new Symbol()
.
Symbol
s in JavaScript
Symbols in JavaScript are a unique and immutable data type used primarily for object property keys to avoid name collisions.
Key characteristics
- Uniqueness: Each Symbol value is unique, even if they have the same description.
- Immutability: Symbol values are immutable, meaning their value cannot be changed.
- Non-enumerable: Symbol properties are not included in for...in loops or Object.keys().
Creating Symbol
s
Symbol
s can be created using the Symbol()
function:
const sym1 = Symbol();const sym2 = Symbol('uniqueKey');console.log(typeof sym1); // "symbol"console.log(sym1 === sym2); // false, because each symbol is unique
The
Symbol(..)
function must be called without thenew
keyword.
Using Symbol
s as object
property keys
Symbol
s can be used to add properties to an object without risk of name collision:
const obj = {};const sym = Symbol('uniqueKey');obj[sym] = 'value';console.log(obj[sym]); // "value"
Symbol
s are not enumerable
Symbol
properties are not included infor...in
loops orObject.keys()
.- This makes them suitable for creating private/internal object state.
- Use
Object.getOwnPropertySymbols(obj)
to get all symbol properties on an object.
const mySymbol = Symbol('privateProperty');const obj = {name: 'John',[mySymbol]: 42,};console.log(Object.keys(obj)); // Output: ['name']console.log(obj[mySymbol]); // Output: 42
Global Symbol
registry
You can create global Symbol
s using Symbol.for('key')
, which creates a new Symbol
in the global registry if it doesn't exist, or returns the existing one. This allows you to reuse Symbol
s across different parts of your code base or even across different code bases.
const globalSym1 = Symbol.for('globalKey');const globalSym2 = Symbol.for('globalKey');console.log(globalSym1 === globalSym2); // trueconst key = Symbol.keyFor(globalSym1);console.log(key); // "globalKey"
Well-known Symbol
JavaScript includes several built-in Symbol
s, referred as well-known Symbol
s.
Symbol.iterator
: Defines the defaultiterator
for an object.Symbol.toStringTag
: Used to create a string description for an object.Symbol.hasInstance
: Used to determine if an object is an instance of a constructor.
Symbol.iterator
let iterable = {[Symbol.iterator]() {let step = 0;return {next() {step++;if (step <= 5) {return { value: step, done: false };}return { done: true };},};},};for (let value of iterable) {console.log(value); // 1, 2, 3, 4, 5}
Symbol.toStringTag
let myObj = {[Symbol.toStringTag]: 'MyCustomObject',};console.log(Object.prototype.toString.call(myObj)); // "[object MyCustomObject]"
Summary
Symbols are a powerful feature in JavaScript, especially useful for creating unique object properties and customizing object behavior. They provide a means to create hidden properties, preventing accidental access or modification, which is particularly beneficial in large-scale applications and libraries.