Skip to content

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

  1. Use symbols for truly private properties
  2. Use Symbol.for() when you need shared symbols
  3. Always provide descriptive names for debugging
  4. 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().