TypeScript Symbol
本节介绍 symbol 类型的语法、使用方法和应用场景,每个从 Symbol()
返回值的唯一性是使用 symbol 类型的最重要原因。
1. 解释
symbol
是一种基本数据类型(primitive data type)。
Symbol()
函数会返回 symbol
类型的值。每个从 Symbol()
返回的 symbol
值都是唯一的。
2. 语法
Symbol([description])
参数 description:可选的,字符串类型。
3. 介绍
使用 Symbol() 创建新的 symbol 类型:
const sym1: symbol = Symbol() const sym2: symbol = Symbol('foo') const sym3: symbol = Symbol('foo')
上面的代码创建了三个新的 symbol 类型,但要注意每个从 Symbol() 返回的值都是唯一的:
console.log(sym2 === sym3) // false
代码解释: 每个 Symbol()
方法返回的值都是唯一的,所以,sym2 和 sym3 不相等。
Symbol() 作为构造函数是不完整的:
const sym = new Symbol() // TypeError
这种语法会报错,是因为从 ECMAScript 6 开始围绕原始数据类型创建一个显式包装器对象已不再被支持,但因历史遗留原因, new Boolean()
、new String()
以及 new Number()
仍可被创建:
const symbol = new Symbol() // TypeError const bigint = new BigInt() // TypeError const number = new Number() // OK const boolean = new Boolean() // OK const string = new String() // OK
4. 使用场景
- 当一个对象有较多属性时(往往分布在不同文件中由模块组合而成),很容易将某个属性名覆盖掉,使用
Symbol
值可以避免这一现象,比如vue-router
中的name
属性。
// a.js 文件 export const aRouter = { path: '/index', name: Symbol('index'), component: Index }, // b.js 文件 export const bRouter = { path: '/home', name: Symbol('index'), // 不重复 component: Home }, // routes.js 文件 import { aRouter } from './a.js' import { bRouter } from './b.js' const routes = [ aRouter, bRouter ]
代码解释: 两个不同文件使用了同样的 Symbol('index')
作为属性 name 的值,因 symbol 类型的唯一性,就避免了重复定义。
- 模拟类的私有方法
const permission: symbol = Symbol('permission') class Auth { [permission]() { // do something } }
这种情况通过类的实例是无法取到该方法,模拟类的私有方法。
但是,TypeScript 是可以使用 private
关键字的,所以这种方法可以在 JavaScript 中使用。
- 判断是否可以用
for...of
迭代
if (Symbol.iterator in iterable) { for(let n of iterable) { console.log(n) } }
这个知识点后续会在 迭代器
那一节会着重介绍,这里可以先知晓:
for...of
循环内部调用的是数据结构的Symbol.iterator
方法。for...of
只能迭代可枚举属性。
- Symbol.prototype.description
Symbol([description])
中可选的字符串即为这个 Symbol 的描述,如果想要获取这个描述:
const sym: symbol = Symbol('mybj') console.log(sym); // Symbol(mybj) console.log(sym.toString()); // Symbol(mybj) console.log(sym.description); // mybj
TIPS: description 属性是 ES2019
的新标准,Node.js 最低支持版本 11.0.0
。
5. 小结
本节介绍了 Symbol 一些常见的使用方法,虽然较少使用,但在特定场景非常有用。