ES6 Symbol数据类型,相信很多人都了解概念,但总不知道在哪可以使用到它。
今天我们就来聊聊,Symbol在实际的开发里可以怎么玩?
一、消除魔术字符串
一般消除魔术字符串的写法是:
const formAKey = 'a-form-key';
const formBKey = 'b-form-key';
const forms = {
formAKey: {
getValue: () => {
return 'I am form A';
}
},
formBKey: {
getValue: () => {
return 'I am form B';
}
}
}
forms.formAKey.getValue() // I am form A
forms.formBKey.getValue() // I am form B
如果forms是全局的,那么你需要考虑一旦重复引起的属性覆盖问题。
由于我们根本不需要关心每次创建的Form key叫什么名字,不冲突即可,有了Symbol我们可以写成这样:
const formAKey = Symbol();
const formBKey = Symbol();
const forms = {
[formAKey]: {
getValue: () => {
return 'I am form A';
}
},
[formBKey]: {
getValue: () => {
return 'I am form B';
}
}
}
forms[formAKey].getValue() // I am form A
forms[formBKey].getValue() // I am form B
二、类的私有属性
由于Symbol的特殊性,当它作为属性值时不会被常规方法遍历得到,所以我们可以利用它来做私有属性,只供内部使用
const sex = Symbol();
class Human {
constructor(){
this.age = 18;
this[sex] = 'female';
}
getSex(){
return this[sex];
}
}
const human = new Human();
human.sex // undefined
human.getSex() // female
Object.keys(human) // ['age']
然而还是有一点缺陷,ES6的另一个新特性可以获取到它:Reflect
Reflect.ownKeys(human) // [ 'age', Symbol() ]
human[Reflect.ownKeys(human)[1]] // female
三、共享体系
Symbol也可以做全局共享,那就是Symbol.for(),它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,且登记在全局环境中供搜索。
const zhangsan = Symbol.for('China');
const chinese = {
[zhangsan]: 'I come from China'
};
const lisi = Symbol.for('China');
chinese[zhangsan] // I come from China
chinese[lisi] // I come from China