位运算的应用

枚举,多选,权限实际是一类问题

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

 

 

参考:

位运算和枚举
位运算符在枚举中的应用 
令你迷惑的位运算
巧用JS位运算

posted @ 2023-12-14 17:01  全玉  阅读(4)  评论(0编辑  收藏  举报