TS基础之枚举扩展知识——位枚举

人生不止有技术

共 4014字,需浏览 9分钟

 · 2021-09-16


前端猎手
 链接每一位开发者,让编程更有趣儿!
关注


大家好!我是法医,一只治疗系前端码猿🐒,与代码对话,倾听它们心底的呼声,期待着大家的点赞👍与关注➕。新手一枚,希望能和大家共同成长,若文章存在哪些不足的地方,欢迎大佬们多提建议

🙉 枚举扩展知识——位枚举

位枚举也可以叫枚举位运算,这里的位枚举针对的是数字枚举,字符串枚举是不行的,这里举个栗子🌰来说明位运算,我们都知道一个文件有很多操作权限,可读可写可创建可删除,权限有对应的取值,这里是数字,不能超过这个范围,如下:

enum Permission{
    Read,
    Write,
    Create,
    Delete
}

以上就是一个文件的四个权限,但是目前有个问题,有的时候我们需要对这些权限进行组合,有的只能读和写不能创建和删除,也许我们会这样写:

enum Permission{
    Read,
    Write,
    Create,
    Delete,
    ReadAndWrite,
    WriteAndCreate,
    //...依次类推,太多了,写不完
}

这四个一组合有A44种排列组合方式,也就是24种结果,如果将来再加点或者删除点字段,那写的就更多了,所以说全写出来放在Permission中非常不方便,那么怎么处理呢?有一种非常巧妙的办法,先把字段分别赋值为1248,如下:

enum Permission{
    Read = 1,
    Write = 2,
    Create = 4,
    Delete = 8
}

我们可以先看下这些数字有什么特点,是不是后面的数字是前面一个的两倍,换句话说,1 = 2^02 = 2^14 = 2^28 = 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中的联合类型哦,这里的叫或运算,它属于位运算其中之一

位运算: 指的是两个数字转换成二进制后用每一位进行的运算,位运算有很多种,|:或运算是其中之一

首先分别拿到的二进制:00010010,它俩进行或运算或运算的规则是用每一位进行比较,有一位是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。比方说00110010进行且运算后的值为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

如果将来我们遇到可选权限方面的场景可以使用位运算的方式进行处理,这种方式非常优雅,扩展性比较好

😊 好了, 以上就是我的分享,小伙伴们点个赞再走吧 👍 支持一下哦~ 😘,我会更有动力的 🤞,晚安!



浏览 18
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报