symbol 是 ES6 中新增的原始数据类型,就像 number 和 string 一样,用于表示独一无二的值。
unique symbol 是 symbol 的子类型,也可以说是 symbol 的加强版。
在 Vue.js 的源码中,有许多地方用到了 unique symbol 类型:
// packages/runtime-core/src/vnode.ts
export const Text: unique symbol = Symbol.for('v-txt')
export const Comment: unique symbol = Symbol.for('v-cmt')
export const Static: unique symbol = Symbol.for('v-stc')
上面代码摘自 Vue.js 3.5.5 版本
unique symbol 类型与 symbol 一样,仅可以通过调用 Symbol() 、Symbol.for() 或者显示类型注解来创建:
const sym1: unique symbol = Symbol.for('sym1');
const sym2: unique symbol = Symbol('sym2');
declare const sym3: unique symbol;
unique symbol 类型只允许在常量声明(const)和只读静态属性(static readonly)上使用,在 let 中声明 unique symbol 类型会报错:
symbol 类型没有这些限制:
class MyClass {
StaticSymbol = Symbol();
}
let sym2 = Symbol.for('sym2');
unique symbol 类型的值也不能够用于互相比对和重新赋值的,例如下面代码中判断两个 unique symbol 类型的值是否相等和重新赋值时,TypeScript 中会报错:
但是换成 symbol 类型的值,是可以进行相互比对和重新赋值的:
let sym1 = Symbol.for('sym');
let sym2 = Symbol.for('sym');
if (sym1 === sym2) {
console.log('相等')
}
sym1 = Symbol('sym1')
上面的代码不会产生报错。
如果使用 const 声明 Symbol() 、Symbol.for() 方法返回的 symbol 值,TypeScript 会自动将其转换为 unique symbol 类型:
总结
symbol 是 ES6 中新增的原始数据类型,用于表示独一无二的值。
在 TypeScript 中,unique symbol 是 symbol 的子类型,也可以说是 symbol 的加强版。注意 JS 中是没有 unique symbol 的,unique symbol 是 Typscript 中的概念。
unique symbol 类型的值只允许在常量声明(const)和只读静态属性(static readonly)上使用,在 let 中声明或非只读静态属性属性上使用会报错,而 symbol 没有这个限制。
unique symbol 类型的值不允许互相比对和重新赋值,symbol 也没有这个限制。同时,使用 const 声明的 Symbol() 、Symbol.for() 方法返回的 symbol 值,TypeScript 会自动将其转换为 unique symbol 类型。
unique symbol 类型有助 TypeScript 提供更强大的类型检查,同时能防止代码中相关的唯一标识被意外的修改,增强代码的健壮性。