Skip to content

Symbol

Symbol.species

用于控制生成新实例时,类的内置方法使用哪个构造器

Symbol.iterator

用于生成对象的迭代器

js
var a = {
    1: '张三',
    2: '12'
};
a[Symbol.iterator] = function () {
    index = 0;
    return {
        next: () => {
            index++;
            return {
                value: this[index],
                done: !this[index]
            };
        }
    };
};

for (var i of a) {
    console.log(i);
    //张三
    //12
}

Symbol.toPrimitive

在做类型转换时,将对象转为原生类型值

js
var arr = [1, 2, 3, 4];

console.log(arr + 10);
// 1,2,3,410

arr[Symbol.toPrimitive] = function (hint) {
    console.log(hint);
    if (hint === 'default' || typeof hint === 'number') {
        return this.reduce((acc, curr) => acc + curr, 0);
    }
};
console.log(arr + 10);
//20

常见的Symbol

以下是 JavaScript 中常用的内置 Symbol 函数及其作用详解,结合实例说明:


🔑 一、对象行为控制类

控制对象在语言原生操作(如迭代、类型转换等)中的默认行为。

  1. Symbol.iterator

    • 作用:定义对象的默认迭代器,使其支持 for...of 循环。
    • 示例
      javascript
      const iterableObj = {
          [Symbol.iterator]: function* () {
              yield 1;
              yield 2;
          }
      };
      for (const num of iterableObj) {
          console.log(num); // 依次输出 1, 2
      }
      数组、MapSet 等内置此迭代器
  2. Symbol.asyncIterator

    • 作用:定义对象的异步迭代器,支持 for await...of 异步遍历。
    • 示例
      javascript
      const asyncObj = {
          async *[Symbol.asyncIterator]() {
              yield Promise.resolve(1);
              yield Promise.resolve(2);
          }
      };
      (async () => {
          for await (const num of asyncObj) {
              console.log(num); // 依次输出 1, 2
          }
      })();
      用于异步数据流(如分页 API)
  3. Symbol.toPrimitive

    • 作用:控制对象转换为原始值(如字符串、数字)的行为。
    • 示例
      javascript
      const obj = {
          [Symbol.toPrimitive](hint) {
              if (hint === 'number') return 100;
              if (hint === 'string') return 'foo';
              return 'default';
          }
      };
      console.log(obj + 1); // "default1"(hint 为 "default")
      console.log(Number(obj)); // 100(hint 为 "number")
      参与运算时自动调用
  4. Symbol.toStringTag

    • 作用:定制 Object.prototype.toString() 返回的标签。
    • 示例
      javascript
      class CustomClass {
          get [Symbol.toStringTag]() {
              return 'MyClass';
          }
      }
      console.log(Object.prototype.toString.call(new CustomClass()));
      // 输出: [object MyClass]
      默认返回 [object Object]

⚙️ 二、运算符与内置方法重写类

覆盖语言原生运算符或方法的行为。

  1. Symbol.hasInstance

    • 作用:自定义 instanceof 运算符的判定逻辑。
    • 示例
      javascript
      class MyArray {
          static [Symbol.hasInstance](instance) {
              return Array.isArray(instance);
          }
      }
      console.log([] instanceof MyArray); // true(原应返回 false)
      改变 instanceof 的默认行为
  2. Symbol.match

    • 作用:重定义 String.prototype.match() 的匹配逻辑。
    • 示例
      javascript
      const customMatcher = {
          [Symbol.match](str) {
              return str.includes('hello') ? 'Found' : null;
          }
      };
      console.log('hello world'.match(customMatcher)); // "Found"
      使非正则对象支持 match()
  3. Symbol.replace / Symbol.search / Symbol.split

    • 作用:分别自定义 String.prototype.replace()search()split() 的行为。
    • 示例Symbol.replace):
      javascript
      const replacer = {
          [Symbol.replace](str, replacement) {
              return str.replace(/foo/, replacement);
          }
      };
      console.log('bar foo'.replace(replacer, 'baz')); // "bar baz"
      扩展字符串方法的功能 .

🧩 三、元编程与构造控制类

影响对象构造或元属性。

  1. Symbol.species

    • 作用:指定派生对象(如 map()filter() 返回的新对象)的构造函数。
    • 示例
      javascript
      class MyArray extends Array {
          static get [Symbol.species]() {
              return Array; // 派生实例使用原生 Array 而非 MyArray
          }
      }
      const arr = new MyArray(1, 2, 3);
      const mapped = arr.map((x) => x * 2);
      console.log(mapped instanceof MyArray); // false
      console.log(mapped instanceof Array); // true
      控制派生对象的类型
  2. Symbol.isConcatSpreadable

    • 作用:控制数组或类数组对象在 concat() 中是否展开。
    • 示例
      javascript
      const arr = [1, 2];
      arr[Symbol.isConcatSpreadable] = false; // 禁止展开
      console.log([].concat(arr)); // 输出: [[1, 2]]
      默认数组展开,类数组对象需显式启用

🌐 四、全局共享与注册类

管理跨模块/环境的 Symbol 共享。

  1. Symbol.for()

    • 作用:从全局注册表获取或创建 Symbol(相同描述符返回同一 Symbol)。
    • 示例
      javascript
      const s1 = Symbol.for('foo');
      const s2 = Symbol.for('foo');
      console.log(s1 === s2); // true
      适用于跨 Realm(如 iframe)共享 Symbol
  2. Symbol.keyFor()

    • 作用:返回全局注册表中 Symbol 的描述字符串(仅限 Symbol.for() 创建的 Symbol)。
    • 示例
      javascript
      const s = Symbol.for('foo');
      console.log(Symbol.keyFor(s)); // "foo"
      查询全局 Symbol 的键名

💎 总结

Symbol核心作用典型场景
Symbol.iterator定义迭代逻辑使对象支持 for...of
Symbol.asyncIterator定义异步迭代逻辑异步数据遍历
Symbol.toPrimitive控制对象转原始值参与运算或类型转换
Symbol.toStringTag定制对象类型标签调试时识别自定义类
Symbol.hasInstance重写 instanceof 行为自定义类型检查
Symbol.species指定派生对象的构造函数控制 map/filter 的返回类型
Symbol.for全局共享 Symbol跨模块/环境使用同一 Symbol

这些内置 Symbol 是 JavaScript 元编程的核心工具,通过覆盖语言底层行为实现高度灵活的定制。