symbol数据类型
symbol的定义
symbol(符号)是es6新增的数据类型,符号是原始值,且符号实例是唯一、不可变的。符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。
一般情况下,重复的属性,后面的会把前面的覆盖掉
let grade = {
lisi: {js:100,css:89},
lisi:{js:35,css:55}
}
console.log(grade["lisi"]);
//{js:35,css:55}
而使用symbol则不会,因为symbol实例是唯一的
在对象中用[ ]括起来,表示该属性是变量,不然会当该属性为字符串
在对象中直接使用symbol实例也要用[ ]括起来
let grade = {
[Symbol('foo')]: {js:100, css: 89 },
[Symbol('bar')]: { js: 35, css: 55 }
};
let user1 = {
name: "李四",
key: Symbol()
};
let user2 = {
name: "李四",
key: Symbol()
};
let grade = {
[user1.key]: { js: 100, css: 89 },
[user2.key]: { js: 35, css: 55 }
};
console.log(grade[user1.key]);
//{ js: 100, css: 89 }
遍历symbol属性
symbol不能使用for/in、for/of直接遍历操作
let symbol = Symbol("demo");
let obj = {
name: "lisi",
[symbol]: "haha"
};
for (const key in obj) {
console.log(key);
}
//name
for (const key of Object.keys(obj)) {
console.log(key);
}
//name
可以使用Object.getOwnPropertySymbols 获取所有symbol属性
for (const key of Object.getOwnPropertySymbols(obj)) {
console.log(key);
}
//Symbol(demo)
也可以使用Reflect.ownKeys获取所有属性(包括symbol)
for (const key of Reflect.ownKeys(obj)) {
console.log(key);
}
//name
//Symbol(demo)
因此symbol跟私有属性有点类似,如果对象属性不想遍历,可以使用symbol保护起来
全局符号注册表
如果运行时的不同部分需要共享和重用符号实例,那么可以用一个字符串作为键,在全局符号注册表中创建并重用符号。
因此,需要使用Symbol.for()方法。第一次使用某个字符串调用时,它会检查全局运行时注册表,发现不存在对应的符号,于是就会生成一个新符号实例并添加到注册表中。后续使用相同字符串的调用同样会检查注册表,发现存在与该字符串对应的符号,然后就会返回该符号实例。
let one = Symbol.for('demo');
let two = Symbol.for('demo');
console.log(one === two);
//true
如果不是使用Symbol.for()方法在全局中注册的话,定义的符号也并不相等。
let one = Symbol.for('demo');
let two = Symbol('demo')
console.log(one === two);
//false