Labs ICT
Pro Login

Symbols

What are Symbols?

Symbol is a primitive data type in JavaScript. Every symbol is unique and immutable. They're often used as unique identifiers for object properties, preventing name collisions when different parts of your code need to add properties to the same object.

const sym1 = Symbol();
const sym2 = Symbol("description");

console.log(sym1 === sym2); // false — every symbol is unique

// Symbols are useful as object keys
const id = Symbol("id");
const user = {
  name: "Alice",
  [id]: 123, // Unique key that won't collide
};

console.log(user[id]); // 123

Well-Known Symbols

JavaScript has several built-in symbols that let you customize how objects behave. For example, Symbol.iterator makes an object iterable with for...of.

class Range {
  constructor(start, end) {
    this.start = start;
    this.end = end;
  }

  [Symbol.iterator]() {
    let current = this.start;
    const end = this.end;

    return {
      next() {
        if (current <= end) {
          return { value: current++, done: false };
        }
        return { done: true };
      },
    };
  }
}

const range = new Range(1, 5);
for (const num of range) {
  console.log(num); // 1, 2, 3, 4, 5
}

Using Symbols as Property Keys

Symbol properties don't show up in for...in loops or Object.keys(). This makes them useful for "hidden" properties that won't interfere with other code.

const secret = Symbol("secret");
const obj = {
  name: "visible",
  [secret]: "hidden",
};

console.log(Object.keys(obj)); // ["name"]
console.log(obj[secret]); // "hidden"

// To get symbol properties:
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(secret)]
Try it Yourself →

Global Symbol Registry

You can create shared symbols using Symbol.for(). These are stored in a global registry and return the same symbol when accessed from anywhere in your code.

const sym1 = Symbol.for("shared");
const sym2 = Symbol.for("shared");

console.log(sym1 === sym2); // true — same symbol from registry

// Get the key for a global symbol
console.log(Symbol.keyFor(sym1)); // "shared"

Summary

Symbols provide unique identifiers and let you customize object behavior through well-known symbols. They're great for avoiding property name conflicts and building more powerful abstractions.