1.什么是symbol
2.应用场景
一.symbol定义
Symbol是 js 新增加的一种基本数据类型,主要用来表示唯一值。
二.应用场景
①作为属性 避免属性冲突重复,就是使用它来表示唯一值;
var dataAtr = Symbol('dataAtr ');
const obj={[dataAtr ]:'属性一定不会冲突',};
问题是我们什么情况下 要保障属性一定不冲突重复 覆盖呢?
在vue里 有this.$parent ,this.$options ,this.$set 这些,使用$命名开头就是想通过命名约定来减少重复覆盖,
可是通过命名约定没有强制执行,还是存在被新生低级程序员覆盖的可能。
在没有Symbol之前 采用 Object.freeze 冻结一个对象 也可以做到 一定不会覆盖修改属性的问题,但是它带来的问题就是失去了灵活性,只想一个属性不被覆盖重复,结果把整个对象都冻结了,这得不偿失。
还要Object.defineProperty(obj,'a',{ writable:false }) 这样通过屏蔽一个属性的可写性 来达到不能覆盖一个属性的目的,不好的地方就是麻烦。用symbol最简单。
要避免冲突覆盖的地方 还有挂在window下的全局方法属性对象等,还有全局状态等,有很多地方需要保障唯一性。
②定义私有属性 私有方法等。
const innerState=Symbol('innerState');
class Person {
constructor(){
this[innerState]=' innerState';//这个内部状态 如果innerState 它导出,别人就无法引用到
}
}
export {Person };
③替代字符串 ,规范代码,减少错误
下面弄一个错误示范
//订单已付款
if(orderStatus==='payed'){
//就干点啥
}
//订单已经取消 就干点啥
if(orderStatus==='cancel'){
//就干点啥
}
这个写法存在的问题是什么呢
1.payed cancel字符串可能在多个地方使用时 书写时出现错误;
2.字符串可能会需要修改,认为它表意不准确
3.别人难以一看就知道 orderStatus到底有哪些状态
采用如下写法 可以完美解决问题
const OrderStatus={
payed:Symbol('payed'),
cancel:Symbol('cancel')
}
//订单已付款
if(orderStatus===OrderStatus.payed){
//就干点啥
}
//订单已经取消 就干点啥
if(orderStatus===OrderStatus.cancel){
//就干点啥
}