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