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().