假设有这样一个场景,我们需要统计员工的技术栈,需要标注的技术有CSS、JavaScript、HTML、WebGL。那么我可以这样写枚举:constSKILLS={CSS:1,JS:2,HTML:3,WEB_GL:4}之前我是这样写的,但是最近看vue源码的时候发现一个高效使用枚举的技巧,在这里分享给大家。定义一个枚举我们可以这样写上面的枚举:constSKILLS={CSS:1,JS:1<<1,HTML:1<<2,WEB_GL:1<<3}<<这是什么?左移运算符(<<)将第一个操作数向左移动指定的位数。多余的左移位被丢弃。零位从右移入。例如:1在二进制中是00000001,向左移动一位是00000010,在十进制中是2。如果我们将它移动两位,它就会变成00000100,也就是十进制的4。如果我们将它移动三位,它就会变成00001000,也就是十进制的8。如果我们将它移动N位,它变成2^Nin十进制。Usage按照上面的方法定义好枚举后,我们可以这样使用:constSKILLS={CSS:1,JS:1<<1,HTML:1<<2,WEB_GL:1<<3}//使用这个值用来存储用户的tech-stacklet技能=0//为用户添加技能函数addSkill(skill){skills=skills|skill}addSkill(SKILLS.CSS)addSkill(SKILLS.JS)//如果这个值不为0,说明用户已经掌握了techconsole.log('DoesheknowCSS',SKILLS.CSS&skills)控制台。log('DoesheknowJavaScript',SKILLS.JS&skills)console.log('DoesheknowWebGL',SKILLS.WEB_GL&skills)提醒:|是按位或运算符,对于每个操作数的对应位为1的每个位位置返回1。consta=5;//00000000000000000000000000000101constb=3;//0000000000000000000000000000011console.log(a|b);//0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000。第一个代表正负,后面的31代表数字。当我们用二进制表示1,1<<2时,它们看起来是这样的:我们定义的枚举变量只有一个二进制形式的1,并且占据了不同的位置。当我们向技能添加枚举选项时,我们使用skills|skill。假设我们现在需要添加的技能是SKILLS.CSS,那么在执行的过程中是:我们可以发现在技能中,SKILLS.CSS对应的位置会变成1,反之我们可以判断是否skills.css是通过检查skills&SKILLS.css的结果是否为0来存在skills中的。顺便说一句,这里我们也可以发现这个技巧有一个缺点,就是枚举项的个数不能超过31个。为什么我们要使用这个技巧?答案很简单,这样的代码运行效率更高。CPU中有直接对应位运算的指令,所以效率更高。我们也可以做性能测试。如果我们不使用位运算,而是使用传统的方法(数组或者map)来实现,那么代码如下。数组方法:constSKILLS={CSS:1,JS:1<<1,HTML:1<<2,WEB_GL:1<<3}//用数组存储用户的tech-stackletskills=[]functionaddSkill(skill){if(!skills.includes(skill)){//避免重复存储skills.push(skill)}}addSkill(SKILLS.CSS)addSkill(SKILLS.JS)skills.includes(SKILLS.CSS)skills.includes(SKILLS.JS)skills.includes(SKILLS.WEB_GL)Mapmethod:constSKILLS={CSS:1,JS:1<<1,HTML:1<<2,WEB_GL:1<<3}//使用一个映射以存储用户的tech-stackletskills={}functionaddSkill(skill){if(!skills[skill]){skills[skill]=true}}addSkill(SKILLS.CSS)addSkill(SKILLS.JS)skills[SKILLS.CSS]skills[SKILLS.JS]skills[SKILLS.WEB_GL]这是来自jsbench.me的性能测试:使用按位枚举,性能明显更高。学习Vue源码我是从Vue源码学习的。exportconstenumShapeFlags{ELEMENT=1,FUNCTIONAL_COMPONENT=1<<1,STATEFUL_COMPONENT=1<<2,TEXT_CHILDREN=1<<3,ARRAY_CHILDREN=1<<4,SLOTS_CHILDREN=1<<5,TELEPORT=1<<6,SUSPENSE=1<<7,COMPONENT_SHOULD_KEEP_ALIVE=1<<8,COMPONENT_KEPT_ALIVE=1<<9,COMPONENT=ShapeFlags.STATEFUL_COMPONENT|ShapeFlags.FUNCTIONAL_COMPONENT}地址:https://github1s.com/vuejs/core/blob/HEAD/packages/shared/src/shapeFlags.ts
