Symbol
Symbol is a primitive data type introduced in ES6. Each Symbol value is unique and immutable. That is what makes Symbols useful as property keys: a Symbol key will not conflict with any other key.
Creating Symbols
const sym1 = Symbol();
const sym2 = Symbol();
console.log(sym1 === sym2); // false - each Symbol is unique
// Symbols can have descriptions (for debugging)
const sym3 = Symbol("mySymbol");
console.log(sym3.toString()); // "Symbol(mySymbol)"
The description is just a label. It does not affect uniqueness:
const a = Symbol("id");
const b = Symbol("id");
console.log(a === b); // false - still unique
Symbols as Property Keys
We can use a Symbol as an object property key. Such a property will not conflict with a string key:
const id = Symbol("id");
const user = {
name: "Alice",
[id]: 12345, // Symbol as key (computed property syntax)
};
console.log(user.name); // "Alice"
console.log(user[id]); // 12345
Symbol Properties are Hidden
Symbol-keyed properties do not appear in normal enumeration:
const secret = Symbol("secret");
const obj = {
visible: "I am visible",
[secret]: "I am hidden",
};
console.log(Object.keys(obj)); // ["visible"]
console.log(JSON.stringify(obj)); // {"visible":"I am visible"}
for (const key in obj) {
console.log(key); // Only logs "visible"
}
// But they can be accessed directly
console.log(obj[secret]); // "I am hidden"
// And retrieved with specific methods
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(secret)]
This makes Symbols useful for adding metadata or internal properties that should not interfere with normal object usage.
Global Symbol Registry
Sometimes we need to share a Symbol across different parts of the code. The global Symbol registry is there for that:
// Create or retrieve a Symbol from the global registry
const globalSym = Symbol.for("app.id");
// Same key returns the same Symbol
const sameSym = Symbol.for("app.id");
console.log(globalSym === sameSym); // true
// Get the key for a registered Symbol
console.log(Symbol.keyFor(globalSym)); // "app.id"
// Regular Symbols are not in the registry
const localSym = Symbol("local");
console.log(Symbol.keyFor(localSym)); // undefined