Symbol 是一种独特的、不可变的 primitive。你创建的每个 Symbol() 都保证是不同的 — 即使两个具有相同的描述也不相等。它们的主要作用是成为防碰撞的对象键。
js
const id = Symbol("id");
const id2 = Symbol("id");
id === id2;
user = { [id]: , : };
user[id];
Symbol 是一种独特的、不可变的 primitive。你创建的每个 Symbol() 都保证是不同的 — 即使两个具有相同的描述也不相等。它们的主要作用是成为防碰撞的对象键。
const id = Symbol("id");
const id2 = Symbol("id");
id === id2;
user = { [id]: , : };
user[id];
Symbol 键属性不会与字符串键冲突,并且从正常的枚举中是隐藏的 — 非常适合附加元数据而不污染对象:
Object.keys(user); // ["name"] — symbol key is skipped
for (const k in user) {} // skips the symbol
JSON.stringify(user); // {"name":"Ann"} — symbol not serialized
Object.getOwnPropertySymbols(user); // [Symbol(id)] — only way to list them
所以库可以通过 Symbol 在你的对象上存储内部数据,而不冒与你的属性冲突或在循环中显示的风险。
最重要的用途 — Symbol.iterator 使对象可迭代:
const range = {
[Symbol.iterator]() {
let i = 1;
return { next: () => (i <= 3 ? { value: i++, done: false } : { done: true }) };
},
};
[...range]; // [1, 2, 3]
其他: Symbol.asyncIterator、Symbol.toPrimitive(自定义强制转换)、Symbol.hasInstance。
Symbol.for("key"); // shared symbol across the whole app (and across realms)
Symbols 启用了无碰撞的元数据键,并让你可以钩入核心语言协议(迭代、强制转换) — 这是内置函数和框架安全地扩展对象的方式。