Guide to JavaScript Symbols
Symbols are primitive values in JavaScript that serve as unique identifiers. They were introduced in ES6 and help prevent naming collisions in object properties.
Creating Symbols
// Basic symbol creation
const sym1 = Symbol();
const sym2 = Symbol('mySymbol'); // With description
// Symbols are always unique
console.log(Symbol() === Symbol()); // false
console.log(Symbol('mySymbol') === Symbol('mySymbol')); // false
// Global symbol registry
const globalSym1 = Symbol.for('globalSymbol');
const globalSym2 = Symbol.for('globalSymbol');
console.log(globalSym1 === globalSym2); // true
// Get symbol description
console.log(Symbol('test').description); // 'test'
Practical Uses
1. Private Properties
const privateProperty = Symbol('private');
class MyClass {
constructor() {
this[privateProperty] = 'hidden';
}
getPrivateValue() {
return this[privateProperty];
}
}
const instance = new MyClass();
console.log(instance[privateProperty]); // 'hidden'
console.log(Object.keys(instance)); // []
2. Preventing Property Collisions
const userId = Symbol('userId');
const userEmail = Symbol('userEmail');
const user = {
[userId]: '12345',
[userEmail]: 'user@example.com',
name: 'John'
};
// Safe from accidental overwrites
user.userId = 'different'; // Won't affect Symbol property
console.log(user[userId]); // '12345'
3. Well-Known Symbols
const myArray = [1, 2, 3];
// Custom iterator using Symbol.iterator
myArray[Symbol.iterator] = function* () {
for (let i = this.length - 1; i >= 0; i--) {
yield this[i];
}
};
// Now iterates in reverse
for (const num of myArray) {
console.log(num); // 3, 2, 1
}
// Other well-known symbols
const obj = {
[Symbol.toPrimitive](hint) {
return hint === 'number' ? 42 : 'hello';
}
};
console.log(+obj); // 42
console.log(`${obj}`); // 'hello'
Best Practices
- Use symbols for truly private properties
- Use Symbol.for() when you need shared symbols
- Always provide descriptive names for debugging
- Use well-known symbols to customize object behavior
Remember: Symbols are not enumerable in for...in
loops and Object.keys()
, but can be accessed via Object.getOwnPropertySymbols()
.