Symbol简单介绍

时间:2024-10-20 07:56:07

JavaScript Symbol

JavaScript Symbol是一种原始数据类型,用于创建唯一的标识符。它们是 ES6 引入的新类型,用于表示唯一的值,可以用作对象的属性名或方法名。

创建 Symbol

Symbol 可以使用 Symbol() 函数创建,且每次调用都会返回一个新的唯一符号。可以传递一个可选的描述字符串作为参数,用于调试目的。

const mySymbol = Symbol('mySymbol');
console.log(mySymbol); // 输出:Symbol(mySymbol)

Symbol 的特性

  • 唯一性:每个 Symbol 都是唯一的,即使使用相同的描述字符串创建,也会得到不同的 Symbol
  • 不可变性:Symbol一旦创建就不能被改变或修改
  • 不可转换性:Symbol不能被转换为其他类型,如字符串或数字

Symbol 的用途

  • 私有属性和方法:Symbol可以用来创建私有属性和方法,防止外部访问

 

class MyClass {
  #privateSymbol = Symbol('private');

  constructor() {
    this[#privateSymbol] = 'Private value';
  }

  #privateMethod() {
    console.log('Private method called');
  }

  publicMethod() {
    console.log(this[#privateSymbol]);
    this.#privateMethod();
  }
}

const obj = new MyClass();
obj.publicMethod(); // 输出:Private value,Private method called

// 尝试访问私有属性和方法
console.log(obj[#privateSymbol]); // 报错:ReferenceError: #privateSymbol is not defined
obj.#privateMethod(); // 报错:SyntaxError: Private field '#privateMethod' must be declared in an enclosing class

在上面的例子中,我们使用 #privateSymbol 创建了一个私有属性和一个私有方法 #privateMethod。我们可以在类的内部访问这些私有成员,但在类的外部则无法访问。注意:在 JavaScript 中,使用 # 符号来声明私有属性和方法是 ECMAScript 2022 中引入的新特性。 

  • 缓存键:Symbol可以用作缓存键,存储和检索值
const cache = new Map();

function getCacheValue(key) {
  if (cache.has(key)) {
    return cache.get(key);
  } else {
    const value = computeValue(key); // 假设 computeValue 是一个计算值的函数
    cache.set(key, value);
    return value;
  }
}

const symbolKey = Symbol('myKey');
const value = getCacheValue(symbolKey);
console.log(value); // 输出:计算出的值

在上面的例子中,我们使用一个 Map 对象作为缓存,Symbols 作为缓存键。由于 Symbols 是唯一的,我们可以确保缓存键是唯一的,从而避免缓存冲突。  

  • 事件名称:Symbol可以用作事件名称,创建唯一的事件.
const eventBus = new EventEmitter();

const EVENT_NAME = Symbol('myEvent');

eventBus.on(EVENT_NAME, () => {
  console.log('事件被触发');
});

eventBus.emit(EVENT_NAME); // 输出:事件被触发

在上面的例子中,我们使用一个 EventEmitter 对象作为事件总线,Symbols 作为事件名称。由于 Symbols 是唯一的,我们可以确保事件名称是唯一的,从而避免事件冲突。 

  • 枚举:Symbol可以用来定义枚举,提供语义化的名称和唯一值
const COLOR = {
  RED: Symbol('red'),
  GREEN: Symbol('green'),
  BLUE: Symbol('blue')
};

console.log(COLOR.RED); // 输出:Symbol(red)
console.log(COLOR.GREEN); // 输出:Symbol(green)
console.log(COLOR.BLUE); // 输出:Symbol(blue)

实际应用

react element中的$$typeof

$$typeof 的值是一个 Symbol,具体来说是 Symbol.for('react.element')。这个 Symbol 是全局唯一的,用于标识 React 元素。

使用 Symbol 作为 $$typeof 的值有以下几个原因:

  • 安全性:Symbols 不能被包含在 JSON 中,这意味着即使服务器有安全漏洞并返回 JSON 而不是文本,JSON 也不能包含 Symbol.for('react.element'),从而防止恶意数据被处理为 React 元素。
  • 全局唯一性:Symbols 是全局唯一的,这意味着即使在不同的环境中(如 iframe 或 worker),Symbol.for('react.element') 也会返回相同的值。