JavaScript中的Symbol类型

63 阅读2分钟

一.为什么要使用 Symbol类型

由于对象的属性名是不能重复的,若出现多个相同的属性名,后一个属性名会覆盖前一个属性名,这个时候就可以使用 Symbol,Symbol 可以理解为一个唯一的字符串。

二.那 Symbol类型是什么

首先,Symbol 是一种基础类型,一个Symbol类型数据可以通过 typeof 关键字校验得到 "symbol" 字符串。

三.那怎么使用 Symbol

1.通过 Symbol() 方法进行初始化

let sy1 = Symbol() // Symbol()
let sy2 = Symbol() // Symbol()
sy1 === sy2 // false

这里 Symbol() 方法返回的是 symbol 类型数据,但是由于 Symbol() 创建的数据具有唯一性,所以 sy1 === sy2 是 false。

2.description 属性

先看如下一段代码

let sy3 = Symbol('123') // Symbol(123)

Symbol() 方法中是可以传入一个字符串作为参数(你不加''或者"",默认也是当作字符串处理),这个参数的作用就是一个描述解释的作用,方便开发者知道这是哪个symbol值。

其次就是,symbol值都有一个 description 属性,调用这个属性会得到解释值的字符串。

let sy4 = Symbol('123')
sy4.description // '123'

3.使用全局符号注册表

如果运行时的不同部分需要共享和重用符号实例,那么可以用一个字符串作为键,在全局符号注册表中创建并重用符号。 所以在此,我们需要使用 Symbol.for() 方法。

let sy5 = Symbol.for('123') // Symbol('123')

由于该方法会对每个字符串键都执行幂等操作。第一次使用某个字符串调用的时候,它会检查全局运行时注册表,发现不存在对应的符号,于是就会生成一个新符号实例并添加到注册表中。后续若使用相同字符串调用同样会检查注册表,发现存在该字符串对应的符号,然后就返回该符号实例。 注意,这里若是采用相同的符号描述,在全局注册表中定义的符号和使用 Symbol() 定义的也并不相同。

let localSymbol = Symbol('foo')
let globalSymbol = Symbol.for('foo')
localSymbol === globalSymbol // false

4.通过 Symbol.keyFor()

还可以通过 Symbol.keyFor() 来查询全局注册表,这个方法接收符号,返回该全局符号对应的字符串键。如果查询的不是全局符号,则返回 undefined。