JavaScript?編寫(xiě)枚舉的最有效方法分享
前言
假設(shè)有這樣一個(gè)場(chǎng)景,我們需要統(tǒng)計(jì)員工的技術(shù)棧,目前我們需要標(biāo)記的技術(shù)有 CSS、JavaScript、HTML、WebGL。
然后我可以這樣寫(xiě)枚舉:
const SKILLS = { CSS: 1 , JS: 2, HTML: 3, WEB_GL: 4 }
之前是這樣寫(xiě)的,但是,最近看vue源碼的時(shí)候,發(fā)現(xiàn)了一個(gè)高效使用枚舉的技巧,在這里分享給大家。
定義枚舉
我們可以這樣寫(xiě)上面的枚舉:
const SKILLS = { CSS: 1 , JS: 1 << 1, HTML: 1 << 2, WEB_GL: 1 << 3 }
<< 是什么?
左移運(yùn)算符 (<<) 將第一個(gè)操作數(shù)左移指定位數(shù)。向左移動(dòng)的多余位被丟棄。零位從右側(cè)移入。
例如:
- 二進(jìn)制的 1 是 0000 0001 ,左移一位是 0000 0010 ,即十進(jìn)制的 2 。
- 如果我們將其移動(dòng)兩位,它將變?yōu)?0000 0100 ,即十進(jìn)制的 4。
- 如果我們將其移動(dòng)三位,它將變?yōu)?0000 1000 ,即十進(jìn)制的 8。
- 如果我們將其移動(dòng) N 位,它將變?yōu)?2^Nin 十進(jìn)制。
用法
按照上面的方法定義好枚舉后,我們可以這樣使用:
const SKILLS = { CSS: 1 , JS: 1 << 1, HTML: 1 << 2, WEB_GL: 1 << 3 } // Use this value to store a user's tech-stack let skills = 0 // add a skill for the user function addSkill(skill) { skills = skills | skill } addSkill(SKILLS.CSS) addSkill(SKILLS.JS) // If this value is not 0, it means that the user has mastered the tech console.log('Does he know CSS', SKILLS.CSS & skills) console.log('Does he know JavaScript', SKILLS.JS & skills) console.log('Does he know Web GL', SKILLS.WEB_GL & skills)
溫馨提示:| 是按位或運(yùn)算符,它在每個(gè)操作數(shù)的對(duì)應(yīng)位為 1 的每個(gè)位位置返回 1。
cons t a = 5; // 00000000000000000000000000000101 const b = 3; // 00000000000000000000000000000011 console.log(a | b); // 00000000000000000000000000000111 // expected output: 7
如何理解這段代碼?
在 JavaScript 中,整數(shù)存儲(chǔ)在 4 個(gè)字節(jié)中,即 32 位。第一個(gè)代表正負(fù),后面的31代表數(shù)字。
當(dāng)我們用二進(jìn)制表示 1 , 1 << 2 時(shí),它們看起來(lái)像這樣:
我們定義的枚舉變量只有一個(gè)二進(jìn)制格式的1,并且占據(jù)不同的位置。
當(dāng)我們向技能添加枚舉選項(xiàng)時(shí),我們使用skills | skill。假設(shè)現(xiàn)在我們需要添加的技能是SKILLS.CSS,那么在執(zhí)行過(guò)程中,就是:
我們可以發(fā)現(xiàn),在技能中,SKILLS.CSS對(duì)應(yīng)的位置會(huì)變成1。反之,那么我們可以通過(guò)查看skills&SKILLS.CSS的結(jié)果是否為0來(lái)判斷技能中是否存在SKILLS.CSS。順便說(shuō)一句,這里我們也可以發(fā)現(xiàn)這個(gè)技巧有個(gè)缺點(diǎn),就是枚舉項(xiàng)不能超過(guò) 31 個(gè)。
我們?yōu)槭裁匆褂眠@個(gè)技巧?
答案很簡(jiǎn)單,這樣的代碼運(yùn)行起來(lái)更高效。CPU中有直接對(duì)應(yīng)位操作的指令,因此效率更高。
我們也可以做一個(gè)性能測(cè)試。如果我們不使用按位運(yùn)算,而是使用傳統(tǒng)的方法(數(shù)組或映射)來(lái)實(shí)現(xiàn),那么代碼如下。
Array 方法:
const SKILLS = { CSS: 1 , JS: 1 << 1, HTML: 1 << 2, WEB_GL: 1 << 3 } // Use an array to store the user's tech-stack let skills = [] function addSkill(skill) { if (!skills.includes(skill)) { // Avoid duplicate storage skills.push(skill) } } addSkill(SKILLS.CSS) addSkill(SKILLS.JS) skills.includes(SKILLS.CSS) skills.includes(SKILLS.JS) skills.includes(SKILLS.WEB_GL)
Map 方法:
const SKILLS = { CSS: 1 , JS: 1 << 1, HTML: 1 << 2, WEB_GL: 1 << 3 } // Use a map to store the user's tech-stack let skills = {} function addSkill(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 的性能測(cè)試:
使用按位枚舉,性能明顯更高。
學(xué)習(xí)Vue源碼
我是從 Vue 源代碼中學(xué)到的。
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 }
到此這篇關(guān)于JavaScript 編寫(xiě)枚舉的最有效方法分享的文章就介紹到這了,更多相關(guān)JavaScript 枚舉編寫(xiě)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
BootStrap自定義popover,點(diǎn)擊區(qū)域隱藏功能的實(shí)現(xiàn)
下面小編就為大家分享一篇BootStrap自定義popover,點(diǎn)擊區(qū)域隱藏功能的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01兼容ie ff div 層 打開(kāi)+關(guān)閉+ 拖動(dòng)+遮罩+移動(dòng)+動(dòng)畫(huà)改變高寬
div層 打開(kāi)+關(guān)閉+ 拖動(dòng)+遮罩+移動(dòng)+動(dòng)畫(huà)改變高寬的實(shí)例js代碼2008-07-07JS實(shí)現(xiàn)禁止用戶使用Ctrl+鼠標(biāo)滾輪縮放網(wǎng)頁(yè)的方法
這篇文章主要介紹了JS實(shí)現(xiàn)禁止用戶使用Ctrl+鼠標(biāo)滾輪縮放網(wǎng)頁(yè)的方法,涉及javascript頁(yè)面元素與事件相關(guān)操作技巧,需要的朋友可以參考下2017-04-04javascript實(shí)現(xiàn)QQ空間相冊(cè)展示源碼
本文給大家分享基于javascript制作的qq空間相冊(cè)展示效果,涉及到html\css布局思維,浮動(dòng)定位詳解,具體實(shí)現(xiàn)代碼大家參考下本文2017-12-12javascript:文字不間斷向左移動(dòng)的實(shí)例代碼
這篇文章介紹了javascript:文字不間斷向左移動(dòng)的實(shí)例代碼,有需要的朋友可以參考一下2013-08-08用innerhtml提高頁(yè)面打開(kāi)速度的方法
這篇文章介紹了用innerhtml提高頁(yè)面打開(kāi)速度的方法,有需要的朋友可以參考一下2013-08-08