Symbol 是 JavaScript 中的一种原始数据类型,ES6(ECMAScript 2015)引入的新特性。Symbol 表示唯一的、不可变的值,通常用作对象属性的标识符。
唯一性:每个 Symbol 值都是唯一的
let sym1 = Symbol();
let sym2 = Symbol();
console.log(sym1 === sym2); // false
不可变性:Symbol 值一旦创建就不能被修改
// 不带描述的 Symbol
let sym1 = Symbol();
// 带描述的 Symbol (仅用于调试)
let sym2 = Symbol('description');
const id = Symbol('id');
let user = {
name: "John",
[id]: 123 // 而不是 "id": 123
};
// 不同库想要向同一个对象添加属性
let obj = {};
// 库1
let lib1_key = Symbol('lib1');
obj[lib1_key] = 'some data';
// 库2
let lib2_key = Symbol('lib2');
obj[lib2_key] = 'other data';
// 不会冲突
const _counter = Symbol('counter');
const _action = Symbol('action');
class Countdown {
constructor(counter, action) {
this[_counter] = counter;
this[_action] = action;
}
tick() {
if (this[_counter]-- === 0) {
this[_action]();
}
}
}
可以使用 Symbol.for()
和 Symbol.keyFor()
在全局 Symbol 注册表中创建和访问 Symbol:
// 从全局注册表创建/获取 Symbol
let globalSym = Symbol.for('app.global');
// 检查 Symbol 是否在全局注册表中
console.log(Symbol.keyFor(globalSym)); // "app.global"
JavaScript 提供了一些内置的 Symbol 值,称为"知名 Symbol",用于语言内部行为:
Symbol.iterator
- 定义对象的默认迭代器Symbol.toStringTag
- 定义对象的默认描述字符串Symbol.hasInstance
- 自定义 instanceof 操作符的行为Symbol.species
- 定义创建派生对象的构造函数class MyClass {
static [Symbol.hasInstance](obj) {
return Array.isArray(obj);
}
}
console.log([] instanceof MyClass); // true
.toString()
)for...in
和 Object.keys()
中 Symbol 属性不可见Object.getOwnPropertySymbols()
获取对象的所有 Symbol 属性JSON.stringify()
会忽略 Symbol 属性Symbol 提供了一种创建唯一标识符的方式,特别适合需要避免命名冲突的场景。