在 TypeScript 中,Symbol 是一种基本数据类型,用来创建唯一的标识符。
你之前写 Go 后端,可以把它理解成一种不会重复的特殊标识符,但它不是 UUID,也不是字符串。
一、最基本的用法
ini
const a = Symbol();
const b = Symbol();
console.log(a === b); // false
即使创建方式完全一样,两个 Symbol 也不相等。
还可以添加描述:
ini
const a = Symbol("id");
const b = Symbol("id");
console.log(a === b); // false
注意:"id" 只是描述信息,不会影响 Symbol 的唯一性。
二、Symbol 可以作为对象的属性名
这是 Symbol 最常见的用途之一。
ini
const id = Symbol("id");
const user = {
name: "张三",
[id]: 1001
};
console.log(user.name); // 张三
console.log(user[id]); // 1001
为什么写 [id]?
因为 Symbol 可以充当对象的属性键,使用方括号可以告诉 TypeScript:使用变量 id 对应的 Symbol 作为属性名。
它的好处是避免属性名冲突。
ini
const id1 = Symbol("id");
const id2 = Symbol("id");
const user = {
[id1]: 1001,
[id2]: 2002
};
console.log(user[id1]); // 1001
console.log(user[id2]); // 2002
虽然两个 Symbol 的描述都是 "id",但它们是不同的属性键。
三、Symbol.for():获取可复用的 Symbol
普通 Symbol() 每次都会创建新的 Symbol。
而 Symbol.for() 会在全局 Symbol 注册表中查找或创建对应的 Symbol。
ini
const a = Symbol.for("user");
const b = Symbol.for("user");
console.log(a === b); // true
对比:
| 写法 | 是否相等 |
|---|---|
Symbol("id") === Symbol("id") |
false |
Symbol.for("id") === Symbol.for("id") |
true |
四、TypeScript 中的 symbol 类型
ini
let id: symbol = Symbol("id");
这里的 symbol 是 TypeScript 类型。
还存在 unique symbol,用于更严格地表示某个独一无二的 Symbol。
ini
const ID: unique symbol = Symbol("id");
const user = {
[ID]: 1001
};
通常使用 const 声明时,TypeScript 就能推断出唯一的 Symbol 类型。
五、Symbol 和 Go 怎么类比?
| 对比 | Go | TypeScript |
|---|---|---|
| 普通字符串标识符 | string |
string |
| 唯一标识符 | 通常使用 UUID 等方案 | Symbol() |
| 用作对象属性键 | map 的 key |
对象的 Symbol 属性键 |
| 是否能跨进程持久化 | UUID 可以 | Symbol 不适合 |
需要注意,Symbol 的唯一性主要用于 JavaScript 运行环境内的标识,不是数据库 ID,不能替代 UUID。
六、总结
最需要记住三个写法:
ini
// 1. 创建唯一 Symbol
const a = Symbol("id");
// 2. 使用 Symbol 作为对象属性名
const user = {
[a]: 1001
};
// 3. 创建或复用注册表中的 Symbol
const b = Symbol.for("id");
一句话总结:Symbol 主要用来创建不会意外冲突的标识符,尤其适合作为对象属性的键。
另外,Symbol 还有 Symbol.iterator 等内置特殊标识符,用于定义对象的迭代等行为。你现在先掌握 Symbol() 和 Symbol.for() 就足够了。