Symbol这个词在IT软件领域实际上是个常见角色,在传统前端技术领域,这个词出现频率有限,但是,随着现代web技术的发展,Symbol这个词开始在不同前端语言中出现。

symbol的中文意思是:符号;象征;标志;记号等。

我最早知道是在Adobe Illustrator软件中,作为一个矢量符号存在。在SVG中,就有专门的<symbol>标签,用来指代SVG小图标。

在这里,Symbol又有了另外的角色,作为一个JavaScript的原生数据类型(primitive data type)存在。

说到JavaScript原生数据类型,我们通常想到的有这6种:undefinednullbooleanstringnumberobject。而symbol是ES6新增的一个原生数据类型。

而Symbol本身又是一个方法。

例如下面JS:

typeof Symbol();

可以看到Symbol()作为一个方法执行了,同时typeof其类型,也是'symbol',如下截图:
image.png
Symbol不能作为构造函数使用,也就是下面这样是会嗝屁的!

new Symbol();

image.png

Symbol的作用是什么?

Symbol的作用非常的专一,换句话说其设计出来就只有一个目的——作为对象属性的唯一标识符,防止对象属性冲突发生。

举个例子,你看上了公司前来的前台妹纸,想了解关于她的更多信息,于是就询问Hr同事,扫地阿姨,于是得到类似这样信息:

let info1 = {
    name: '婷婷',
    age: 24,
    job: '公司前台',
    description: '平时喜欢做做瑜伽,人家有男朋友,你别指望了'
}
let info2 = {
    description: '这小姑娘挺好的,挺热情的,嘿嘿嘿……'
}

显然,你需要对这两个数据进行汇总,结果,就会发现,描述都用了同一个对象属性description,于是整合的时候,就容器冲突,覆盖,导致“人家有男朋友”这么重要的信息都没注意到。

但是,如果要是Symbol,则完全就不要担心这个问题了:

let info1 = {
    name: '婷婷',
    age: 24,
    job: '公司前台',
    [Symbol('description')]: '平时喜欢做做瑜伽,人家有男朋友,你别指望了'
}
let info2 = {
    [Symbol('description')]: '这小姑娘挺好的,挺热情的,嘿嘿嘿……'
}

此时,我们对info1, info2对象进行复制,如下:

let target = {};
Object.assign(target, info1, info2);

此时target对象如下截图所示:
image.png

妹纸所有的描述信息都被完完整整地保留了下来了。

因为Symbol()返回值是唯一的,也就是:

Symbol('description') === Symbol('description');    // 返回值是false

Symbol()的语法

语法如下:

Symbol([description])

其中description为可选参数,字符串,没什么特别的作用,就是debug调试的时候可以用来作为标记。

如何获取Symbol()对应属性值?

拿上面target举例,如何获得对妹纸的description描述信息呢?

我们可以使用Object.getOwnPropertySymbols(obj)这个方法进行获取,可以返回obj对象中的Symbol信息,例如:

Object.getOwnPropertySymbols(target);

妹纸的描述信息就出现了,如下截图:

image.png


墨城
1.7k 声望2.1k 粉丝