Skip to content

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] = 123obj.foo = 123obj[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

Proxy

Template String(css in js)

Bigint

Genarator, async iterable