位运算的应用
枚举,多选,权限实际是一类问题
1. 枚举
对于状态值,一般不推荐过多的状态值全放在同一个集合内。原因是每一个枚举项都会占用二进制的一个位数。
枚举类型中可枚举的范围一般是Int64的范围。但如果要进行或运算,需要用无符号的整形进行运算。
也就是一般枚举最大可定义 0到1 << 30的,共32位枚举项。0一般是不用作枚举项的,也就是说,最多支持31位枚举项。
let Enum = { a : 1, // 1 << 0就是1,简化节约性能 b : 1 << 1, c : 1 << 2, d : 1 << 3 }
增加枚举
let myEnum = Enum.a | Enum.b;
myEnum |= Enum.c;
删除枚举
myEnum ^= Enum.a;
myEnum &= ~Enum.a;
判断枚举
myEnum & Enum.a
用 Status = Status & (^状态项),可以关闭状态
2. 表单多选
// 假设我们封装的组件提供以下 tab 名称的板块内容,并按顺序排列 const optArr = ["看书", "散步", "看电影"]; // 假设我们需要展示:["看书", "散步"],对应的下标分别是:[0, 1,2] const optIndex = (1 << 0) + (1 << 1) + (1 << 2); //3 // 通用写法 const optIndex; optArr.forEach((item,index) => { if(item.checked){ optIndex |= (1 << index); } }) // 传值 optIndex = 3 const optArr = ["看书", "散步", "看电影"]; const newOptArr = optArr.filter((_, key) => { const num = 1 << key; return (optIndex & num) === num; }); // ["看书", "散步"]
3. 权限
let permission1 = 0 // 无任何权限 let permission2 = TEXT // 1 >> 0 let permission3 = CLASS // 1 >> 1 // 初始化一个新的用户角色 permission4 并初始化,初始化角色即无权限状态 0 let permission4 = 0 // 赋予 TEXT(1 >> 0) 权限 permission4 |= TEXT // 赋予 CLASS(1 << 1) 权限 permission4 |= CLASS // 新的组合类型的用户角色权限即 00000011 ,如下 permission4 = 0 | TEXT | CLASS // 0 = 0000 0000 // TEXT = 0000 0001 // CLASS = 0000 0010 // ----------------------- // permission4 = 0000 0011 // 权限校验,& 对比二进制操作位 permission4 & TEXT // 0000 0011 & 0000 0001 = 0000 0001 = 1 = true permission4 & CLASS // 0000 0011 & 0000 0010 = 0000 0010 = 2 = true permission4 & STYLE // 0000 0011 & 0000 0100 = 0000 0000 = 0 = false
4. 计算相关
4.1 判断是否等于-1
~x = -x - 1
~-1 = 0
if(!~str.indexOf("n")){ }
等价于
if(str.indexOf("n") == "-1"){ }
4.2 取整
~~x
4.3 判断奇偶数
偶数 & 1 // 0
奇数 & 1 // 1
参考: