Symbol类型的变量

66 阅读2分钟

Symbol 是什么?

Symbol 是 ES6 引入的一种新的数据类型,它的作用是用来生成唯一的标识符。每个 Symbol 都是独一无二的,即使你创建的 Symbol 描述相同,它们也不会相等。

怎么创建 Symbol?

创建 Symbol 很简单,直接调用 Symbol() 函数就行。你可以给它传个描述,主要是为了调试时看得清楚,但这并不会影响它的唯一性。

const sym1 = Symbol('desc');  // 有描述
const sym2 = Symbol('desc');  // 还是不同的实例

Symbol 有什么特点?

  1. 唯一性:每个 Symbol 都是唯一的,不能和其他 Symbol 比较相等。

    const sym1 = Symbol('id');
    const sym2 = Symbol('id');
    console.log(sym1 === sym2);  // false
    
  2. 不可变性:一旦创建,Symbol 就不能修改,没法像字符串那样变来变去。

  3. 不能自动转换成字符串:如果你想把 Symbol 打印出来,必须调用 .toString() 方法。

    const sym = Symbol('hello');
    console.log(sym.toString());  // "Symbol(hello)"
    

Symbol 的用途

  1. 避免属性冲突:在大型项目中,不同模块可能会用到相同的属性名。用 Symbol 作为属性名,就能确保它们唯一,不会被覆盖。

    const uniqueKey = Symbol('unique');
    const obj = {
      [uniqueKey]: 'value'
    };
    console.log(obj[uniqueKey]);  // 'value'
    
  2. 模拟私有属性:JavaScript 对象的属性是公开的,没法像传统 OOP 那样定义私有属性。使用 Symbol,你可以模拟私有属性,这样外部无法直接访问。

    const privateKey = Symbol('private');
    const obj = {
      [privateKey]: 'This is private'
    };
    console.log(obj[privateKey]);  // 'This is private'
    
  3. 实现迭代器:如果你需要自定义对象的迭代行为,可以通过 Symbol.iterator 来实现。

    const myIterable = {
      [Symbol.iterator]: function() {
        let i = 0;
        const data = ['a', 'b', 'c'];
        return {
          next: function() {
            if (i < data.length) {
              return { value: data[i++], done: false };
            } else {
              return { done: true };
            }
          }
        };
      }
    };
    
    for (const item of myIterable) {
      console.log(item);  // a, b, c
    }
    
  4. 全局唯一的标识符:如果你想在整个应用中共享一个唯一标识符,可以使用 Symbol.for(),它会在全局注册这个 Symbol

    const sym1 = Symbol.for('shared');
    const sym2 = Symbol.for('shared');
    console.log(sym1 === sym2);  // true
    

常见方法

  • Symbol.for() :查找全局注册的 Symbol,如果没有找到就创建一个新的。
  • Symbol.keyFor() :获取已经注册的全局 Symbol 的描述。
  • Object.getOwnPropertySymbols() :获取对象的符号属性(仅限对象本身的,不包括继承的)。
  • Reflect.ownKeys() :获取对象的所有键,包括符号键和普通键。

总结

Symbol 的核心作用就是生成独一无二的标识符,它避免了属性名冲突、模拟私有属性、实现特殊功能等多种用途。如果你需要在一个复杂的应用中确保标识符的唯一性,或者想要定义私有属性,Symbol 就是一个很有用的工具。