偶然间,我发现了一种前端枚举的新玩法。起初一脸懵逼,心想:“这是啥?”
缓过神来,直呼“精妙!牛哔!效率贼高!”
尝试在公司的项目里用了用,确实感觉程序的执行效率变快了(当然,肯定有心理暗示)。
当周CodeReview时,同事们惊了:
让我们看看就是怎样的一种玩法!
一、枚举定义/***SKILLS:面试者的技能枚举**/constSKILLS={CSS:1,JS:11,HTML:12,WEB_GL:13}
枚举的定义看起来平平无奇,但又有些奇怪,是吗?
解释下:
符号是js中的位操作符,1N的意思是:将数字1的位向左移动N位。
11//2//二进制:1=//4//二进制:10=...1N//2的N次方二、枚举使用
我们按照“步骤一”里的方式定义了枚举,那应该怎么使用呢?
假设一个场景:当我们面试一个前端同学时,我们会不断标记他有哪些技能,这个添加标记的过程如下:
letskills=0//增加一项他会的技能functionaddSkill(skill){skills=skills
skill//加上}addSkill(SKILLS.CSS)//1addSkill(SKILLS.HTML)//5addSkill(SKILLS.WEB_GL)//13
完成了技能的添加,我们就需要在其他地方开销这个人具备什么技能了,开销过程如下:
//判断他是否会CSSSKILLS.CSSskills//1(0代表不会,非0代表会)//判断他是否会JSSKILLS.JSskills//0(0代表不会,非0代表会)//判断他是否会HTML且会WebGlSKILLS.HTMLskillsSKILLS.WEB_GLskills//8(0代表不会,非0代表会)//判断他是否会JS或会HTMLSKILLS.JSskills
SKILLS.HTMLskills
OK!基本能力具备了。
有同学要问了:“它有什么优点?可读性这么差!”
当然有优点,优点就在于:它效率贼高!
三、效率对比为了验证它的“效率有多高”,我写了两个常见的“对照组”写法来进行验证。
常见写法一:数组式玩法letskills=[]functionaddSkill(skill){if(!skills.includes(skill)){//判断技能术里是否有该技能skills.push(skill)}}addSkill(SKILLS.CSS)//1addSkill(SKILLS.HTML)//5addSkill(SKILLS.WEB_GL)//13skills.includes(SKILLS.CSS)skills.includes(SKILLS.JS)skills.includes(SKILLS.HTML)skills.includes(SKILLS.WEB_GL)skills.includes(SKILLS.JS)
skills.includes(SKILLS.HTML)
这种写法,使用一个数组来存储技能枚举,再通过arr.includes()方法来判断枚举是否已被存储。
常见写法二:Map式玩法letskills={}functionaddSkill(skill){if(!(skills[skill])){//判断技能术里是否有该技能skills[skill]=true}}addSkill(SKILLS.CSS)//1addSkill(SKILLS.HTML)//5addSkill(SKILLS.WEB_GL)//13skills[SKILLS.CSS]skills[SKILLS.JS]skills[SKILLS.HTML]skills[SKILLS.WEB_GL]skills[SKILLS.JS]
skills[SKILLS.HTML]
这种方法则是通过{[value]:true}的方式来存储枚举,然后再通过map[value]的方式进行取值,来判断枚举是否已被存储。
对比结果猜猜看,三种方式的效率排名会怎样?结果如下:最快组:位运算组(本文推荐的玩法)
每秒执行11亿次
第二名:数组式玩法
每秒执行万次
最慢组:Map式玩法
每秒执行万次
用例