Symbol这个词在IT软件领域实际上是个常见角色,在传统前端技术领域,这个词出现频率有限,
但是,随着现代web技术的发展,Symbol这个词开始在不同前端语言中出现。
symbol的中文意思是:符号;象征;标志;记号等。
作为一个JavaScript的原生数据类型(primitive data type)存在。
说到JavaScript原生数据类型,我们通常想到的有这6种:
undefined、null、boolean、string、number、object。
而symbol是ES6新增的一个原生数据类型。
而Symbol本身又是一个方法。
例如下面JS:
typeof Symbol()===>>>>'symbol',
symbol类型显示
但Symbol不能作为构造函数使用,否则或报错 XXX new Symbol();
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====>>>{
age: 24,
job: "公司前台",
name: "婷婷",
Symbol(description): "平时喜欢做做瑜伽,人家有男朋友,你别指望了",
Symbol(description): "这小姑娘挺好的,挺热情的,嘿嘿嘿……"
}
因为Symbol()返回值是唯一的,也就是:
Symbol('description') === Symbol('description'); // 返回值是false
Symbol()的语法
Symbol('description') target 对象不能遍历description 属性
也不能想使用正常对象的属性eg:target["description"] ==undefind
let description=Symbol(["description"])
这样命名就可以正常访问属性及遍历
如何获取Symbol()对应属性值?
拿上面target举例,如何获得对妹纸的description描述信息呢?
//我们可以使用Object.getOwnPropertySymbols(obj)这个方法进行获取,
//可以返回obj对象中的Symbol信息,例如:Object.getOwnPropertySymbols(target);
妹纸的描述信息
Symbol在和对象使用的时候,往往离不开JS中的数组括号[],例如:
var smy = Symbol();
var info = {
smy: 'x',
[smy]: 'y'
};
此时:
console.log(info.smy); // 输出'x'
console.log(info['smy']); // 输出'x'
console.log(info[smy]); // 输出'y'
Symbol其他一些知识
1. Symbol与运算、类型转换等
symbol值虽然不是对象,但是根据自己测试,在Chrome和Firefox下都是可以添加属性的,例如:
var smy = Symbol();
smy.description = '描述';
//在macos chrome 65.0.3325.181和node v8.9.4中测试给symbol加属性结果是undefined
//与上面window PC测试结果有些细节差异。
使用宽松相等时, Object(sym) == sym返回值是true。注意这里外面套的是Object();
2. Symbol与for…in迭代
Symbols在for...in迭代中不可枚举,如果想要达到效果,借助Object.getOwnPropertySymbols(obj)这个方法。
var obj = {};
obj[Symbol("a")] = "a";
obj[Symbol.for("b")] = "b";
obj["c"] = "c";
obj.d = "d";
for (var i in obj) {
console.log(i); // 输出 "c" 和 "d"
}
3. Symbol与JSON.stringify()
当使用JSON.strIngify()时以symbol值作为键的属性会被完全忽略,示意代码:
JSON.stringify({[Symbol("foo")]: "foo"}); // '{}'