Symbol
就是创建一个全局唯一的符号,无论传入的值是什么(也就是说传入的值可以作为一个方便调试时增加语义的注释而已)
调用方式 | 是否复用 | 是否全局共享 |
---|---|---|
Symbol() | ❌ 每次新建 | ❌ 不共享 |
Symbol.for(key) | ✅ 会复用 | ✅ 全局注册表 |
特性/维度 | Symbol 作为 Property Key | 普通 Property Key(字符串或数字) |
---|---|---|
唯一性 | 全局唯一(每次 Symbol() 生成不同值) | 可以重复(同名键会覆盖) |
可枚举性 | 默认不可枚举(for…in / Object.keys 不会列出) | 默认可枚举(除非手动设置 enumerable: false ) |
序列化 | 被 JSON.stringify 忽略 | 正常出现在 JSON 结果中 |
隐式转换 | 不能自动转为字符串或数字 | 可自动转为字符串(如 "1" 与 1 等价) |
访问方式 | 只能通过原始 Symbol 值或变量访问 | 可通过点语法或字符串/数字字面量访问 |
创建方式 | Symbol() 、Symbol.for() | 直接写键名或表达式 |
调试友好性 | 可选描述(不影响唯一性) | 键名即描述 |
覆盖风险 | 几乎为零(唯一标识) | 高(同名键会覆盖) |
示例 | obj[mySym] = 123 | obj.foo = 123 、obj[1] = 123 |
javascript
// 1) Symbol.for / Symbol.keyFor -------------------------------------------------
const share1 = Symbol.for('global.shared');
const share2 = Symbol.for('global.shared');
console.log('share1 === share2 ?', share1 === share2); // true
console.log('key →', Symbol.keyFor(share1)); // global.shared
// 2) Symbol.isConcatSpreadable -----------------------------------------------
const fakeArr = { 0: 'a', 1: 'b', length: 2 };
fakeArr[Symbol.isConcatSpreadable] = true; // 告诉 concat 按数组展开
console.log([0].concat(fakeArr)); // [0, 'a', 'b']
// 3) Symbol.iterator(同步迭代器)---------------------------------------------
class Range {
constructor(from, to) {
this.from = from;
this.to = to;
}
*[Symbol.iterator]() { // 同步迭代逻辑
for (let i = this.from; i <= this.to; i++) yield i;
}
}
console.log('...Range(3,5):', ...new Range(3, 5)); // 3 4 5
// 4) Symbol.asyncIterator(异步迭代器)----------------------------------------
class DelayCounter {
constructor(max) { this.max = max; }
async *[Symbol.asyncIterator]() { // 异步迭代逻辑
for (let i = 1; i <= this.max; i++) {
await new Promise(r => setTimeout(r, 200)); // 异步延迟
yield i;
}
}
}
(async () => {
for await (const n of new DelayCounter(3)) console.log('async:', n);
})();
// 5) Symbol.toStringTag(自定义类型标签)--------------------------------------
class MyType {
get [Symbol.toStringTag]() { return 'MyType'; }
}
const obj = new MyType();
console.log(Object.prototype.toString.call(obj)); // [object MyType]
WeakSet/Map
Reflect+ Decorator(ts)
Arrow this, lexical env
- 非严格模式全局this指向window,严格则是undefined