TS基础之枚举扩展知识——位枚举
共 4014字,需浏览 9分钟
·
2021-09-16 15:18
大家好!我是法医,一只治疗系前端码猿🐒,与代码对话,倾听它们心底的呼声,期待着大家的点赞👍与关注➕。新手一枚,希望能和大家共同成长,若文章存在哪些不足的地方,欢迎大佬们多提建议
🙉 枚举扩展知识——位枚举
位枚举
也可以叫枚举位运算
,这里的位枚举针对的是数字枚举,字符串枚举是不行的,这里举个栗子🌰来说明位运算
,我们都知道一个文件有很多操作权限,可读
、可写
、可创建
、可删除
,权限有对应的取值,这里是数字,不能超过这个范围,如下:
enum Permission{
Read,
Write,
Create,
Delete
}
以上就是一个文件的四个权限,但是目前有个问题,有的时候我们需要对这些权限进行组合,有的只能读和写不能创建和删除,也许我们会这样写:
enum Permission{
Read,
Write,
Create,
Delete,
ReadAndWrite,
WriteAndCreate,
//...依次类推,太多了,写不完
}
这四个一组合有A44
种排列组合方式,也就是24种结果,如果将来再加点或者删除点字段,那写的就更多了,所以说全写出来放在Permission中非常不方便,那么怎么处理呢?有一种非常巧妙的办法,先把字段分别赋值为1
、2
、4
、8
,如下:
enum Permission{
Read = 1,
Write = 2,
Create = 4,
Delete = 8
}
我们可以先看下这些数字有什么特点,是不是后面的数字是前面一个的两倍,换句话说,1 = 2^0
,2 = 2^1
,4 = 2^2
,8 = 2^4
,它们全是2的n次方,如果换算成二进制的话,它们其中一位是1,其余是0,1的二进制是0001
,2的二进制是0010
,4的二进制是0100
,8的二进制是1000
,我们可以通过二进制某一位上是否有1来表示是否有这个权限,比如0001
第四位上是1表示有读的权限,再比如:0011
可以表示有读和写的权限,所以我们可以通过这些基本权限来组合新的权限
🍓 1.如何组合新的权限
比如说我们要组合读
和写
的权限,可以这样:
enum Permission{
Read = 1, //0001
Write = 2, //0010
Create = 4,//0100
Delete = 8 //1000
}
//1. 如何组合类型
//使用 或 运算
let rwP = Permission.Read | Permission.Write;
我们需要注意的是这里的|
可不是TS
中的联合类型
哦,这里的叫或运算
,它属于位运算
其中之一
位运算
: 指的是两个数字转换成二进制后用每一位进行的运算,位运算有很多种,|:或运算
是其中之一
首先分别拿到读
和写
的二进制:0001
,0010
,它俩进行或运算
,或运算
的规则是用每一位进行比较,有一位是1,那么结果就是1,否则为0,所以最后结果是0011
0001
//或运算
0010
//最后结果是 0011
🍎 2.如何判断是否拥有某个权限
经过或运算的处理后,rwP
会得到一个数字,将它作为目标值传入函数中与权限进行对比
enum Permission{
Read = 1, //0001
Write = 2, //0010
Create = 4,//0100
Delete = 8 //1000
}
//1. 如何组合类型
//使用位运算
let rwP = Permission.Read | Permission.Write;
/**
* 判断target里面包不包含p这个权限
* @param target 目标值
* @param p 某个权限
*/
function hasPermission(target:Permission,p:Permission) {
return (target & p) === p
}
//判断rwP有没有“读”这个权限
let result = hasPermission(rwP,Permission.Read);
//判断rwP是否拥有Read权限
console.log(result);//返回true
其实判断是否拥有某个权限很简单,要判断是否有Read
这个权限,只要判断它的二进制0001
最后一位是不是等于1
就行了。
我们再来看这段代码(target & p) === p
,其中&
叫做且运算
,它也是位运算
中一种
且运算
:比较两个数的二进制,只要当两个数的二进制相同位置上都是1的时候才是1
,反之为0
。比方说0011
和0010
进行且运算后的值为0010
,再与权限相比,相等则表示拥有这个权限,反之没有。
🍒 3.如何删除某个权限
enum Permission{
Read = 1, //0001
Write = 2, //0010
Create = 4,//0100
Delete = 8 //1000
}
//1. 如何组合类型
//使用位运算
let rwP = Permission.Read | Permission.Write;
/**
* 判断target里面包不包含p这个权限
* @param target 目标值
* @param p 某个权限
*/
function hasPermission(target:Permission,p:Permission) {
return (target & p) === p
}
//判断rwP有没有“读”这个权限
let result = hasPermission(rwP,Permission.Read);
// 3. 如何删除某个权限
rwP = rwP ^ Permission.Write;
console.log(hasPermission(rwP,Permission.Write));//返回false表示清除了可写的权限
删除某个权限可以通过rwP = rwP ^ Permission.Write;
重新赋值就可以了,这段代码中^
表示异或
异或
:比较两个数字的二进制,两者相同位置的数字最后结果取0
,不同取1
,比方说之前的权限是0011
,要删除0010
读的权限,最后结果是0001
如果将来我们遇到可选权限方面的场景可以使用位运算
的方式进行处理,这种方式非常优雅,扩展性比较好
😊 好了, 以上就是我的分享,小伙伴们点个赞再走吧 👍 支持一下哦~ 😘,我会更有动力的 🤞,晚安!