TS基礎(chǔ)之枚舉擴展知識——位枚舉

大家好!我是法醫(yī),一只治療系前端碼猿??,與代碼對話,傾聽它們心底的呼聲,期待著大家的點贊??與關(guān)注?。新手一枚,希望能和大家共同成長,若文章存在哪些不足的地方,歡迎大佬們多提建議
?? 枚舉擴展知識——位枚舉
位枚舉也可以叫枚舉位運算,這里的位枚舉針對的是數(shù)字枚舉,字符串枚舉是不行的,這里舉個栗子??來說明位運算,我們都知道一個文件有很多操作權(quán)限,可讀、可寫、可創(chuàng)建、可刪除,權(quán)限有對應(yīng)的取值,這里是數(shù)字,不能超過這個范圍,如下:
enum Permission{
Read,
Write,
Create,
Delete
}
以上就是一個文件的四個權(quán)限,但是目前有個問題,有的時候我們需要對這些權(quán)限進行組合,有的只能讀和寫不能創(chuàng)建和刪除,也許我們會這樣寫:
enum Permission{
Read,
Write,
Create,
Delete,
ReadAndWrite,
WriteAndCreate,
//...依次類推,太多了,寫不完
}
這四個一組合有A44種排列組合方式,也就是24種結(jié)果,如果將來再加點或者刪除點字段,那寫的就更多了,所以說全寫出來放在Permission中非常不方便,那么怎么處理呢?有一種非常巧妙的辦法,先把字段分別賦值為1、2、4、8,如下:
enum Permission{
Read = 1,
Write = 2,
Create = 4,
Delete = 8
}
我們可以先看下這些數(shù)字有什么特點,是不是后面的數(shù)字是前面一個的兩倍,換句話說,1 = 2^0,2 = 2^1,4 = 2^2,8 = 2^4,它們?nèi)?的n次方,如果換算成二進制的話,它們其中一位是1,其余是0,1的二進制是0001,2的二進制是0010,4的二進制是0100,8的二進制是1000,我們可以通過二進制某一位上是否有1來表示是否有這個權(quán)限,比如0001第四位上是1表示有讀的權(quán)限,再比如:0011可以表示有讀和寫的權(quán)限,所以我們可以通過這些基本權(quán)限來組合新的權(quán)限
?? 1.如何組合新的權(quán)限
比如說我們要組合讀和寫的權(quán)限,可以這樣:
enum Permission{
Read = 1, //0001
Write = 2, //0010
Create = 4,//0100
Delete = 8 //1000
}
//1. 如何組合類型
//使用 或 運算
let rwP = Permission.Read | Permission.Write;
我們需要注意的是這里的|可不是TS中的聯(lián)合類型哦,這里的叫或運算,它屬于位運算其中之一
位運算: 指的是兩個數(shù)字轉(zhuǎn)換成二進制后用每一位進行的運算,位運算有很多種,|:或運算是其中之一
首先分別拿到讀和寫的二進制:0001,0010,它倆進行或運算,或運算的規(guī)則是用每一位進行比較,有一位是1,那么結(jié)果就是1,否則為0,所以最后結(jié)果是0011
0001
//或運算
0010
//最后結(jié)果是 0011
?? 2.如何判斷是否擁有某個權(quán)限
經(jīng)過或運算的處理后,rwP會得到一個數(shù)字,將它作為目標值傳入函數(shù)中與權(quán)限進行對比
enum Permission{
Read = 1, //0001
Write = 2, //0010
Create = 4,//0100
Delete = 8 //1000
}
//1. 如何組合類型
//使用位運算
let rwP = Permission.Read | Permission.Write;
/**
* 判斷target里面包不包含p這個權(quán)限
* @param target 目標值
* @param p 某個權(quán)限
*/
function hasPermission(target:Permission,p:Permission) {
return (target & p) === p
}
//判斷rwP有沒有“讀”這個權(quán)限
let result = hasPermission(rwP,Permission.Read);
//判斷rwP是否擁有Read權(quán)限
console.log(result);//返回true
其實判斷是否擁有某個權(quán)限很簡單,要判斷是否有Read這個權(quán)限,只要判斷它的二進制0001最后一位是不是等于1就行了。
我們再來看這段代碼(target & p) === p,其中&叫做且運算,它也是位運算中一種
且運算:比較兩個數(shù)的二進制,只要當兩個數(shù)的二進制相同位置上都是1的時候才是1,反之為0。比方說0011和0010進行且運算后的值為0010,再與權(quán)限相比,相等則表示擁有這個權(quán)限,反之沒有。
?? 3.如何刪除某個權(quán)限
enum Permission{
Read = 1, //0001
Write = 2, //0010
Create = 4,//0100
Delete = 8 //1000
}
//1. 如何組合類型
//使用位運算
let rwP = Permission.Read | Permission.Write;
/**
* 判斷target里面包不包含p這個權(quán)限
* @param target 目標值
* @param p 某個權(quán)限
*/
function hasPermission(target:Permission,p:Permission) {
return (target & p) === p
}
//判斷rwP有沒有“讀”這個權(quán)限
let result = hasPermission(rwP,Permission.Read);
// 3. 如何刪除某個權(quán)限
rwP = rwP ^ Permission.Write;
console.log(hasPermission(rwP,Permission.Write));//返回false表示清除了可寫的權(quán)限
刪除某個權(quán)限可以通過rwP = rwP ^ Permission.Write;重新賦值就可以了,這段代碼中^表示異或
異或:比較兩個數(shù)字的二進制,兩者相同位置的數(shù)字最后結(jié)果取0,不同取1,比方說之前的權(quán)限是0011,要刪除0010讀的權(quán)限,最后結(jié)果是0001
如果將來我們遇到可選權(quán)限方面的場景可以使用位運算的方式進行處理,這種方式非常優(yōu)雅,擴展性比較好
?? 好了, 以上就是我的分享,小伙伴們點個贊再走吧 ?? 支持一下哦~ ??,我會更有動力的 ??,晚安!
