JS声明定义Symbol的几种方式及简单应用

it2025-04-07  18

首先,我们先来谈谈,什么是Symbol呢?Symbol是ES6新增的一种数据类型。

那么这种数据类型到底应该怎么用呢,让我们先开看看普通字符串的声明吧。

let name = 'Joker'; let title = 'Joker'; console.log(name === title) //true

当我们拿两个值相同的字符串进行比较的时候,返回的结果为true。

let name = Symbol(); let title = Symbol(); console.log(name === title) //false

但如果我们声明两个Symbol类型的时候,他们是永远不会一样的,所以打印的结果为false。因此我们可以把Symbol理解为一种唯一标识符。简单理解,我们可以把Symbol当成是一个永远不会重复的字符串。

除此之外,我们还能在Symbol里面添加相应的描述(通过描述能清楚区分该symbol的作用是什么)。

let name = Symbol('我的英文名为Joker'); console.log(name) //Symbol(我的英文名为Joker)

此时我们打印这个Symbol的时候就能看到Symbol类型和相应的描述了。

另外系统还给我们提供了一个名为description的属性,我们通过这个属性能获取到symbol的描述信息。

console.log(name.description) //我的英文名为Joker

除了上面这种定义symbol的方式外,我们还能通过Symbol.for的方式定义。

let name = Symbol.for("我的英文名为Joker"); console.log(name.description) //我的英文名为Joker

这两种定义的方式的区别在于:如果我们通过Symbol.for的方式定义的话,系统会帮我们记录有一个Symbol且它的描述为"我的英文名为Joker",在下一次定义symbol的时候,系统就会先查询内存中是否已经声明了一个相同的symbol,如果有就把Symbol拿过来。因此,即使我们用Symbol.for声明一百次一千次,实际上就只有一个Symbol。但通过Symbol()的方式声明则不同,如果我们声明一百次,那么就有一百个Symbol。

let name = Symbol.for("我的英文名为Joker"); let title = Symbol.for("我的英文名为Joker"); console.log(name === title) //true

这里的Symbol虽然看起来是两个,但却指向的是同一个symbol,因此这里的打印结果为true。

除此之外,二者之间还有一个区别:

let name = Symbol.for("我的英文名为Joker"); let title = Symbol("我的英文名为Joker"); console.log(Symbol.keyFor(name)); //我的英文名为Joker console.log(Symbol.keyFor(title)); //undefined

通过Symbol.for的方式声明的时候,是在全局定义的,因此可以通过Symbol.keyFor()的方式获取到Symobl的描述。

但通过Symbol()的声明方式则不是全局定义的,因此得到的值为undefined。

好了关于Symbol这一个新增的数据类型相信大家已经有了初步的了解,接下来让我们来看看Symbol应该用在什么场景上呢?

假如有一个对象里面存着一次考试的学生成绩,但由于这次测试的学生名字都为“Joker”,但对象的属性名却要唯一,这可怎么办呢?这时候我们就可以使用我们的Symbol()啦。

let student1 = { name: "Joker", key: Symbol() }; let student2 = { name: "Joker", key: Symbol() }; let test = { [student1.key]: {js: 100, css: 89}, [student2.key]: {js: 55, css: 68} }; console.log(test)

这时候就能顺利的把两个学生的考试信息都打印出来了。

思路:将Symbol作为我们对象的key值,由于Symbol()是唯一的,因此我们再也不怕对象的属性值重复的问题啦。

不过如果我们把Symbol作为对象的属性名,那么普通的for in和for of是不能遍历出来的,这时候我们就要用特殊的遍历方法。

for (const key of Reflect.ownKeys(test)) { console.log(key); }

 

最新回复(0)