JS使用位運算實現(xiàn)權(quán)限組合的代碼示例
在業(yè)務(wù)開發(fā)中我們經(jīng)常會遇到處理不同權(quán)限的情況,例如根據(jù)用戶角色是否有編輯權(quán)限來展示和隱藏一個按鈕,或者一個函數(shù)根據(jù)傳入的配置項來執(zhí)行不同的邏輯,也就是所謂的權(quán)限控制。
在判斷用戶是否擁有某個權(quán)限時,一般情況下我們會這樣寫:
// 用戶信息
const userInfo = {
permission: 1
};
const READ = 0; // 讀取權(quán)限
const WRITE = 1; // 寫入權(quán)限
const DELETE = 1; // 刪除權(quán)限
// 判斷用戶是否有刪除權(quán)限
if(userInfo.perssion === DELETE) {
// do something...
}
但如果要判斷是否同時擁有讀取和刪除權(quán)限時,上面這種方法就做不到了,因為只能判斷一種權(quán)限。在多于一種權(quán)限的組合狀態(tài)下,就需要用到位運算了。
例如在Loash的baseClone方法里,使用了bitmask參數(shù)來判斷是否深度克隆,是否克隆symbols等。


普通的克隆方法clone和深度克隆方法cloneDeep基于baseClone封裝而來,兩者的區(qū)別是在第二個參數(shù)的值有區(qū)別,這里就是運用了位運算。


接下來讓我們一起研究下這個位運算是個什么東西。
1、位運算概述
現(xiàn)代計算機中所有的數(shù)據(jù)是以二進(jìn)制的形式存儲在設(shè)備中的。即 0、1 兩種狀態(tài),計算機對二進(jìn)制數(shù)據(jù)進(jìn)行的運算(+、-、*、/)都是叫位運算。
2、位運算符概覽
| 符號 | 描述 | 運算規(guī)則 |
|---|---|---|
| & | 與 | 兩個位都為1時,結(jié)果才為1 |
| | | 或 | 兩個位都為0時,結(jié)果才為0 |
| 異或 | 兩個位相同為0,相異為1 | |
| ~ | 取反 | 0變1,1變0 |
| << | 左移 | 各二進(jìn)位全部左移若干位,高位丟棄,低位補0 |
| >> | 右移 | 各二進(jìn)位全部右移若干位,對無符號數(shù),高位補0,有符號數(shù),各編譯器處理方法不一樣,有的補符號位(算術(shù)右移),有的補0(邏輯右移) |
3、位運算實現(xiàn)權(quán)限組合
既然位運算是以二進(jìn)制數(shù)據(jù)做運算,因此我們可以用二進(jìn)制數(shù)定義權(quán)限變量。
const READ = 0b0001; // 讀取權(quán)限 const WRITE = 0b0010; // 寫入權(quán)限 const DELETE = 0b0100; // 刪除權(quán)限 // 或 const READ = 1; const WRITE = 2; const DELETE = 4;
1)權(quán)限組合(添加權(quán)限)
上面已經(jīng)定義了讀、寫、刪三個單獨權(quán)限。如果要定義一個讀寫權(quán)限,需要怎么定義呢。
根據(jù)|運算符的規(guī)則可知,當(dāng)兩個位中只要有一個為1,結(jié)果為1。因此可以這樣定義讀寫權(quán)限:
const READ = 0b0001; // 讀取權(quán)限 const WRITE = 0b0010; // 寫入權(quán)限 // 組合讀寫權(quán)限 const READ_WRITE = READ | WRITE; // 0b0011
2)權(quán)限切換
當(dāng)用戶擁有讀權(quán)限,就刪除用戶的讀權(quán)限;當(dāng)用戶沒有讀權(quán)限,就添加讀權(quán)限。這樣的權(quán)限切換,要怎么實現(xiàn)呢。
根據(jù)^運算符規(guī)則可知,當(dāng)兩個位相同時為0,相異為1。
// 當(dāng)兩個值相等時,結(jié)果為0。即自己與自己做異或運算時,結(jié)果為0。 0b0001 ^ 0b0001 // 0b0000 // 一個0值與目標(biāo)做異或運算時,得到目標(biāo)值。 0b0000 ^ 0b0001 // 0b0001
因此,要切換哪個權(quán)限,只需要與該權(quán)限做異或運算就可以了。
const READ = 0b0001; // 讀取權(quán)限 const WRITE = 0b0010; // 寫入權(quán)限 // 用戶權(quán)限 let userPermission = READ | WRITE; // 0b0011 讀寫權(quán)限 // 切換讀取權(quán)限 userPermission = userPermission ^ READ; // 0b0010 第一次執(zhí)行,刪除讀權(quán)限 userPermission = userPermission ^ READ; // 0b0011 第二次執(zhí)行,添加讀權(quán)限
3)判斷權(quán)限組合中是否擁有某個權(quán)限
當(dāng)用戶擁有一個權(quán)限組合,怎么判斷用戶是否擁有某個權(quán)限呢。
根據(jù)&運算符規(guī)則可知,當(dāng)兩個位都為1時結(jié)果為1,否則結(jié)果為0。
// 自己與自己做與運算時,結(jié)果為自己。 0b0001 & 0b0001 // 0b0001 // 一個0值與目標(biāo)做與運算時,結(jié)果為0。 0b0000 & 0b0001 // 0b0000
因此,要判斷是否擁有某個權(quán)限,只需要與該權(quán)限做與運算,與運算結(jié)果為該權(quán)限的值則代表擁有該權(quán)限。
const READ = 0b0001; // 讀取權(quán)限 const WRITE = 0b0010; // 寫入權(quán)限 // 用戶權(quán)限 const userPermission = READ | WRITE; // 0b0011 // 判斷是否有讀權(quán)限 const hasReadPermission = (userPermission & READ) === READ; // true
4)刪除權(quán)限組合中的某個權(quán)限
如果用戶擁有讀寫權(quán)限,想要刪掉用戶的讀權(quán)限,需要怎樣實現(xiàn)呢。
由以上可知,需要先判讀是否有讀權(quán)限,有的話就做異或運算切換(刪除)該權(quán)限。
const READ = 0b0001; // 讀取權(quán)限
const WRITE = 0b0010; // 寫入權(quán)限
// 用戶權(quán)限
const userPermission = READ | WRITE; // 0b0011
const hasPermission = (userPermission, value) => {
return (userPermission & value) === value;
};
// 刪除讀權(quán)限
if(hasPermission(userPermission, READ)) {
userPermission = userPermission ^ READ;
};
以上就是JS使用位運算實現(xiàn)權(quán)限組合的代碼示例的詳細(xì)內(nèi)容,更多關(guān)于JS位運算實現(xiàn)權(quán)限組合的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
layer彈窗在鍵盤按回車將反復(fù)刷新的實現(xiàn)方法
今天小編就為大家分享一篇layer彈窗在鍵盤按回車將反復(fù)刷新的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
用JavaScript實現(xiàn)瀏覽器截圖功能的全過程
在Web開發(fā)中實現(xiàn)網(wǎng)頁截圖功能可以幫助我們保存網(wǎng)頁內(nèi)容、生成海報、制作截圖分享等,這篇文章主要介紹了用JavaScript實現(xiàn)瀏覽器截圖功能的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-07-07
js操作XML文件的實現(xiàn)方法兼容IE與FireFox
下面小編就為大家?guī)硪黄猨s操作XML文件的實現(xiàn)方法兼容IE與FireFox。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06
使用ngrok+express解決本地環(huán)境中微信接口調(diào)試問題
這篇文章主要介紹了使用ngrok+express解決本地環(huán)境中微信接口調(diào)試問題,需要的朋友可以參考下2018-02-02

