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')
也会返回相同的值。