JS使用位運(yùn)算實(shí)現(xiàn)權(quán)限組合的代碼示例
在業(yè)務(wù)開(kāi)發(fā)中我們經(jīng)常會(huì)遇到處理不同權(quán)限的情況,例如根據(jù)用戶角色是否有編輯權(quán)限來(lái)展示和隱藏一個(gè)按鈕,或者一個(gè)函數(shù)根據(jù)傳入的配置項(xiàng)來(lái)執(zhí)行不同的邏輯,也就是所謂的權(quán)限控制。
在判斷用戶是否擁有某個(gè)權(quán)限時(shí),一般情況下我們會(huì)這樣寫:
// 用戶信息 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... }
但如果要判斷是否同時(shí)擁有讀取和刪除權(quán)限時(shí),上面這種方法就做不到了,因?yàn)橹荒芘袛嘁环N權(quán)限。在多于一種權(quán)限的組合狀態(tài)下,就需要用到位運(yùn)算了。
例如在Loash
的baseClone
方法里,使用了bitmask
參數(shù)來(lái)判斷是否深度克隆,是否克隆symbols等。
普通的克隆方法clone
和深度克隆方法cloneDeep
基于baseClone
封裝而來(lái),兩者的區(qū)別是在第二個(gè)參數(shù)的值有區(qū)別,這里就是運(yùn)用了位運(yùn)算。
接下來(lái)讓我們一起研究下這個(gè)位運(yùn)算是個(gè)什么東西。
1、位運(yùn)算概述
現(xiàn)代計(jì)算機(jī)中所有的數(shù)據(jù)是以二進(jìn)制的形式存儲(chǔ)在設(shè)備中的。即 0、1 兩種狀態(tài),計(jì)算機(jī)對(duì)二進(jìn)制數(shù)據(jù)進(jìn)行的運(yùn)算(+、-、*、/)都是叫位運(yùn)算。
2、位運(yùn)算符概覽
符號(hào) | 描述 | 運(yùn)算規(guī)則 |
---|---|---|
& | 與 | 兩個(gè)位都為1時(shí),結(jié)果才為1 |
| | 或 | 兩個(gè)位都為0時(shí),結(jié)果才為0 |
異或 | 兩個(gè)位相同為0,相異為1 | |
~ | 取反 | 0變1,1變0 |
<< | 左移 | 各二進(jìn)位全部左移若干位,高位丟棄,低位補(bǔ)0 |
>> | 右移 | 各二進(jìn)位全部右移若干位,對(duì)無(wú)符號(hào)數(shù),高位補(bǔ)0,有符號(hào)數(shù),各編譯器處理方法不一樣,有的補(bǔ)符號(hào)位(算術(shù)右移),有的補(bǔ)0(邏輯右移) |
3、位運(yùn)算實(shí)現(xiàn)權(quán)限組合
既然位運(yùn)算是以二進(jìn)制數(shù)據(jù)做運(yùn)算,因此我們可以用二進(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)定義了讀、寫、刪三個(gè)單獨(dú)權(quán)限。如果要定義一個(gè)讀寫權(quán)限,需要怎么定義呢。
根據(jù)|
運(yùn)算符的規(guī)則可知,當(dāng)兩個(gè)位中只要有一個(gè)為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)用戶沒(méi)有讀權(quán)限,就添加讀權(quán)限。這樣的權(quán)限切換,要怎么實(shí)現(xiàn)呢。
根據(jù)^
運(yùn)算符規(guī)則可知,當(dāng)兩個(gè)位相同時(shí)為0,相異為1。
// 當(dāng)兩個(gè)值相等時(shí),結(jié)果為0。即自己與自己做異或運(yùn)算時(shí),結(jié)果為0。 0b0001 ^ 0b0001 // 0b0000 // 一個(gè)0值與目標(biāo)做異或運(yùn)算時(shí),得到目標(biāo)值。 0b0000 ^ 0b0001 // 0b0001
因此,要切換哪個(gè)權(quán)限,只需要與該權(quán)限做異或運(yù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)限組合中是否擁有某個(gè)權(quán)限
當(dāng)用戶擁有一個(gè)權(quán)限組合,怎么判斷用戶是否擁有某個(gè)權(quán)限呢。
根據(jù)&
運(yùn)算符規(guī)則可知,當(dāng)兩個(gè)位都為1時(shí)結(jié)果為1,否則結(jié)果為0。
// 自己與自己做與運(yùn)算時(shí),結(jié)果為自己。 0b0001 & 0b0001 // 0b0001 // 一個(gè)0值與目標(biāo)做與運(yùn)算時(shí),結(jié)果為0。 0b0000 & 0b0001 // 0b0000
因此,要判斷是否擁有某個(gè)權(quán)限,只需要與該權(quán)限做與運(yùn)算,與運(yùn)算結(jié)果為該權(quán)限的值則代表?yè)碛性摍?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)限組合中的某個(gè)權(quán)限
如果用戶擁有讀寫權(quán)限,想要?jiǎng)h掉用戶的讀權(quán)限,需要怎樣實(shí)現(xiàn)呢。
由以上可知,需要先判讀是否有讀權(quán)限,有的話就做異或運(yù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使用位運(yùn)算實(shí)現(xiàn)權(quán)限組合的代碼示例的詳細(xì)內(nèi)容,更多關(guān)于JS位運(yùn)算實(shí)現(xiàn)權(quán)限組合的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
js實(shí)現(xiàn)div的切換特效上一個(gè)下一個(gè)
實(shí)現(xiàn)div切換的方法有很多,下面為大家介紹下使用js是如何實(shí)現(xiàn)的2014-02-02微信小程序如何同時(shí)獲取用戶信息和用戶手機(jī)號(hào)
小程序登錄是現(xiàn)在小程序里面很普遍的一個(gè)功能,因?yàn)楣俜教峁┑姆椒?可以一鍵獲取到用戶信息,一鍵拿到手機(jī)號(hào),這篇文章主要給大家介紹了關(guān)于微信小程序如何同時(shí)獲取用戶信息和用戶手機(jī)號(hào)的相關(guān)資料,需要的朋友可以參考下2021-08-08

一個(gè)JS小玩意 幾個(gè)屬性相加不能超過(guò)一個(gè)特定值.

JS解決移動(dòng)web開(kāi)發(fā)手機(jī)輸入框彈出的問(wèn)題