JS使用位运算实现权限组合的代码示例
在业务开发中我们经常会遇到处理不同权限的情况,例如根据用户角色是否有编辑权限来展示和隐藏一个按钮,或者一个函数根据传入的配置项来执行不同的逻辑,也就是所谓的权限控制。
在判断用户是否拥有某个权限时,一般情况下我们会这样写:
// 用户信息 const userInfo = { permission: 1 }; const READ = 0; // 读取权限 const WRITE = 1; // 写入权限 const DELETE = 1; // 删除权限 // 判断用户是否有删除权限 if(userInfo.perssion === DELETE) { // do something... }
但如果要判断是否同时拥有读取和删除权限时,上面这种方法就做不到了,因为只能判断一种权限。在多于一种权限的组合状态下,就需要用到位运算了。
例如在Loash
的baseClone
方法里,使用了bitmask
参数来判断是否深度克隆,是否克隆symbols等。
普通的克隆方法clone
和深度克隆方法cloneDeep
基于baseClone
封装而来,两者的区别是在第二个参数的值有区别,这里就是运用了位运算。
接下来让我们一起研究下这个位运算是个什么东西。
1、位运算概述
现代计算机中所有的数据是以二进制的形式存储在设备中的。即 0、1 两种状态,计算机对二进制数据进行的运算(+、-、*、/)都是叫位运算。
2、位运算符概览
符号 | 描述 | 运算规则 |
---|---|---|
& | 与 | 两个位都为1时,结果才为1 |
| | 或 | 两个位都为0时,结果才为0 |
异或 | 两个位相同为0,相异为1 | |
~ | 取反 | 0变1,1变0 |
<< | 左移 | 各二进位全部左移若干位,高位丢弃,低位补0 |
>> | 右移 | 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) |
3、位运算实现权限组合
既然位运算是以二进制数据做运算,因此我们可以用二进制数定义权限变量。
const READ = 0b0001; // 读取权限 const WRITE = 0b0010; // 写入权限 const DELETE = 0b0100; // 删除权限 // 或 const READ = 1; const WRITE = 2; const DELETE = 4;
1)权限组合(添加权限)
上面已经定义了读、写、删三个单独权限。如果要定义一个读写权限,需要怎么定义呢。
根据|
运算符的规则可知,当两个位中只要有一个为1,结果为1。因此可以这样定义读写权限:
const READ = 0b0001; // 读取权限 const WRITE = 0b0010; // 写入权限 // 组合读写权限 const READ_WRITE = READ | WRITE; // 0b0011
2)权限切换
当用户拥有读权限,就删除用户的读权限;当用户没有读权限,就添加读权限。这样的权限切换,要怎么实现呢。
根据^
运算符规则可知,当两个位相同时为0,相异为1。
// 当两个值相等时,结果为0。即自己与自己做异或运算时,结果为0。 0b0001 ^ 0b0001 // 0b0000 // 一个0值与目标做异或运算时,得到目标值。 0b0000 ^ 0b0001 // 0b0001
因此,要切换哪个权限,只需要与该权限做异或运算就可以了。
const READ = 0b0001; // 读取权限 const WRITE = 0b0010; // 写入权限 // 用户权限 let userPermission = READ | WRITE; // 0b0011 读写权限 // 切换读取权限 userPermission = userPermission ^ READ; // 0b0010 第一次执行,删除读权限 userPermission = userPermission ^ READ; // 0b0011 第二次执行,添加读权限
3)判断权限组合中是否拥有某个权限
当用户拥有一个权限组合,怎么判断用户是否拥有某个权限呢。
根据&
运算符规则可知,当两个位都为1时结果为1,否则结果为0。
// 自己与自己做与运算时,结果为自己。 0b0001 & 0b0001 // 0b0001 // 一个0值与目标做与运算时,结果为0。 0b0000 & 0b0001 // 0b0000
因此,要判断是否拥有某个权限,只需要与该权限做与运算,与运算结果为该权限的值则代表拥有该权限。
const READ = 0b0001; // 读取权限 const WRITE = 0b0010; // 写入权限 // 用户权限 const userPermission = READ | WRITE; // 0b0011 // 判断是否有读权限 const hasReadPermission = (userPermission & READ) === READ; // true
4)删除权限组合中的某个权限
如果用户拥有读写权限,想要删掉用户的读权限,需要怎样实现呢。
由以上可知,需要先判读是否有读权限,有的话就做异或运算切换(删除)该权限。
const READ = 0b0001; // 读取权限 const WRITE = 0b0010; // 写入权限 // 用户权限 const userPermission = READ | WRITE; // 0b0011 const hasPermission = (userPermission, value) => { return (userPermission & value) === value; }; // 删除读权限 if(hasPermission(userPermission, READ)) { userPermission = userPermission ^ READ; };
以上就是JS使用位运算实现权限组合的代码示例的详细内容,更多关于JS位运算实现权限组合的资料请关注脚本之家其它相关文章!
相关文章
webpack踩坑系列之less-loader6.0.0的javascriptEnabled报错问题
这篇文章主要介绍了webpack踩坑系列之less-loader6.0.0的javascriptEnabled报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-01-01JavaScript声明变量的这四兄弟(var、let、function、const)
这篇文章主要介绍了JavaScript声明变量的这四兄弟,主要就是介绍var、let、function、const区别,需要的朋友可以参考下2023-02-02Js 利用正则表达式和replace函数获取string中所有被匹配到的文本(推荐)
这篇文章主要介绍了Js 利用正则表达式和replace函数获取string中所有被匹配到的文本,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧2018-10-10uni-app 项目中 “文件查找失败:‘crypto-js‘“ 的问题及解决方法
在开发使用 uni-app 框架的项目时,遇到依赖问题是常见的,本文将介绍如何解决编译过程中出现的 “文件查找失败:‘crypto-js’” 错误,并说明这种错误为什么会发生以及如何避免,下面分步骤给大家带来解决方案,感兴趣的朋友一起看看吧2024-07-07
最新评论