偶然间,我发现了一种前端枚举 的新玩法。起初一脸懵逼,心想:“这是啥?”
缓过神来,直呼“精妙!牛哔!效率贼高!”
尝试在公司的项目里用了用,确实感觉程序的执行效率变快了(当然,肯定有心理暗示)。
当周 Code Review
时,同事们惊了:

让我们看看就是怎样的一种玩法!
一、枚举定义
/** * SKILLS:面试者的技能枚举 **/ const SKILLS = { CSS: 1 , JS: 1 << 1, HTML: 1 << 2, WEB_GL: 1 << 3 }
枚举的定义看起来平平无奇,但又有些奇怪,是吗?
解html代码释下:
<<
符号是 js
中的位操作符,1 << N
的意思是:将数字 1
的位向左移动 N
位。
1 << 1 // 2 // 二进制:1 => 10 1 << 2 // 4 // 二进制:10 => 100 ... 1 << N // 2的N次方
二、枚举使用
我们按照 “步骤一” 里Git的方式定义了枚举,那应该怎么使用呢?
假设一个场景:当我们面试一个前端同学时,我html个人网页完整代码们会不断标记他有哪些技能,github直播平台永久回家这个添加标记的过程如下:
let skills = 0 // 增加一项他会的技能 function addSkill(skill) { skills = skills | skill // 加上 } addSkill(SKILLS.CSS) // 1 addSkill(SKILLS.HTML) // 5 addSkill(SKILLS.WEB_GL) // 13
完成了技能的添加,我们就需要在其他地方开销这github是干什么的个人具备什么技能了giti轮胎,开销过程如下:
// 判断他是否会 CSS SKILLS.CSS & skills // 1 (0 代表不会,非0代表会) // 判断他是否会 JS SKILLS.JS & skills // 0 (0 代表不会,非0代表会) // 判断他是否会 HTML 且会 WebGl SKILLS.HTML & skills && SKILLS.WEB_GL & skills // 8 (0 代表不会,非0代表会) // 判断他是否会 JS 或会 HTML SKILLS.JS & skills || SKILLS.HTML & skills
OK!基本能力具备了。
有同学要问了:“它有什么优点?可读性github下载这么差!”
当然有优点,优点就在于:它效率 贼高!
三、效率对比
为了验证它的“效率有多高”,我写了两个常见的“对照组”写法github中文官网网页来进行验证。
常见写法一:数组式玩法
let skills = [] function addSkill(skill) { if (!skills.includes(skill)) { // 判断技能术里是否有该技能 skills.push(skill) } } addSkill(SKILLS.CSS) // 1 addSkill(SKILLS.HTML) // 5 addSkill(SKILLS.WEB_GL) // 13 skills.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.include从山神开始的诸天之旅s()
方法来判断枚举是否已被存储。github中文官网网页
常见写法二:Map
式玩法
let skills = {} function addSkill(skill) { if (!(skills[skill])) { // 判断技能术里是否有该技能 skills[skill] = true } } addSkill(SKILLS.CSS) // 1 addSkill(SKILLS.HTML) // 5 addSkill(SKILLS.WEB_GL) // 13 skills[SKILLS.CSS] skills[SKILLS.JS] skills[SKILLS.HTML] && skills[SKILLS.WEB_GL] skills[SKILLS.JS] || skills[SKILLS.HTML]
这种方法则是通过 { [value]: true }
的方式来存储枚举,然后再通过 map[value]
的方式进行取值,来判断枚举是否已陈涉世家翻译及原文被存储。
对比结果
猜猜看,三种方式的效率排名会怎样?
结果如下:
最快组:位运算组(本文推荐的玩法)
每秒执行 11 亿次
第二名:数组式玩法
每秒执行 3124 万次
最慢组:Map
式玩法
每html网页制作秒执行 952 万次
用例地址: jsbench.me/4okyr97qi9/…
感兴趣的朋友可访问上面的链辰时是几点到几点接进行自行验证。
按结果分析,最快
与 最慢
之间甚至有 2-3
个数据级的差别。
四、原理分析(为啥这么快!)
本文推荐的“位运算式”为什么效率这么高?它又是怎么通过位运算完成上述内容的功能的?
4.1 定义原理
这得从 Javascript
中整型的数据格式说起,有符号整数使用 31 位表示整数的数值,用第 32
位表示整数的符号,0
表示正数,1
表示负数。github中文官网网页数值范围为 [-2^31,2^31-1]
,即[ -2147483648, 2147483647]。

因此,这种方式仅仅适前端工程师合少于等于31个枚举项 的场景。
4.2 存值原理
为什么 skills = skills | skill
这串代码能表示 在 skills
中增加了一个枚举项 ?
|
是 Javascript
中的位前端开发需要学什么运算符:或。
当两个数值进行 |
运算时,会焯是什么梗对每一位进行比较,任何一位上,如果两个数都为 0
,则结果为 0
;其余情况结果为 1
;
例如:
1 << 1 | 1 << 2 // 010 | 100 // 结果为 110,即数字:6 1 | 1 << 3 // 0001 | 1000 // 结果为 1001,即数字:9
因此,只要执行github直播平台永久回家过 skills = skills | skill
,其结果中,ski前端ll
对应前端开发的那一位上一定存在一个 1
。
4.3 取值原理
为什么 SKILLS.CSS & skills
返回 非0
值时,可以代表 skihtml标签lls
上包含 SKILLS.CSS
?反之则不包含?
&
是 Javascript
中的html是什么意思运算符:且 。
当两个数值进行 &
运算时,会对每一位进行比github是干什么的较,任何一位上如果两个数都为 1
,则结果为 1
;其余情况结果为 0
;
例如:
1 & 9 // 0001 & 1001 = 0001 (1) 2 & 8 // 0010 & 1000 = 0000 (0)
因此,SKILLS.CSShtml网页制作 & skills
返回 非0
值时,就能判定 skills
中一定存在 SKILLS.CSS
。
五、谁在用?(尤雨溪:正是在下)
以上用法我是从哪里看到的呢?
没错,正是从 vue3
源码中看到的。
源码地址:github1s.com/vuhtml个人网页完整代码ejs/core/…
在该源码中,vue3
通过焯是什么梗此种方式定义枚举,开销枚举,非常值得我们学习。
ShapeFlags
的枚举定义方式:
export const enum ShapeFlags { 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 }
结束
我是春哥
。
我热爱 vue.js
, ElementUI
, ECSSlement Pl仓鼠饲养八大禁忌us
相关技术栈,我的目标是给大家分享最实用、最有用的知识点,希望github下载大家都可以早早下班,并可以飞速完成工作,淡定摸鱼。
你可以在关注我:春哥的梦想是摸鱼
,前端开发也可以HTML在公众号里找到我:前端要摸鱼
。
希望大家在 2022 变得更强。
评论(0)