二进制位操作符应用场景

文章目录

  • 前言
  • 位操作符
    • << 左移运算符
    • | 按位或运算符
    • & 按位与运算符
    • ^ 按位异或运算符
  • 应用场景对比
    • 不使用位操作符
    • 使用位操作符
  • vue3中应用的场景

前言

之前在阅读一些源码时总能看到左位移等一些位操作符,关于位操作符其实很早就有学习过,只不过不理解应用场景,所以看到也不知道为什么要这么使用,但能明白是某种状态声明,这次有时间就了解一下应用场景并简要记录一下

位操作符

这里只简要说明本文涉及到的位操作符,更多位操作符可看:MDN
过程中涉及到数字不大,容我忽略本应该32位或64位二进制码

<< 左移运算符

左移运算符将数字转为二进制后向左移动n次,并在右侧补n个0

const num = 1;
// 转为二进制 00001
// 向左位移2位 得 00100
console.log(num << 2); // 转十进制:4

| 按位或运算符

按位或运算符将数字转为二进制后 对比每一位数是1则为1
简单说是有1为1,全0为0

const num1 = 1; // 00001
const num2 = 2; // 00010

// 对比每一位 有1反1 得 00011
console.log(num1 | num2); // 转十进制:3

& 按位与运算符

按位与运算符将数字转为二进制后 对比每一位数全1则为1
简单说是全1为1,有0为0

const num1 = 1; // 00001
const num2 = 2; // 00010

// 对比每一位 全1反1 得 00000
console.log(num1 & num2); // 转十进制:0

^ 按位异或运算符

按位异或运算符将数字转为二进制后 对比每一位数全0为0 不同为1
简单说是相同为0,不同为1

const num1 = 1; // 00001
const num2 = 3; // 00011

// 对比每一位 相同为0 得 00010
console.log(num1 ^ num2); // 转十进制:2

应用场景对比

了解了上面的位操作符现在可以尝试应用到场景中进行对比。
假设实现一个权限管理的场景该如何做呢(这里只做模拟权限管理,真实场景权限管理可以参考rbac等设计模型)

不使用位操作符

这里就用常用的函数封装方法来使用

 const user = [1]; // 默认拥有访问权限

 const FUNCTION_POINT = {
     add: 2,
     edit: 3,
     delete: 4
 }

 const addPermission = (type) => {
     user.push(FUNCTION_POINT[type]);
 }
 const checkPermission = (type) => {
     return user.includes(FUNCTION_POINT[type]);
 }
 const deletePermission = (type) => {
     const index = user.indexOf(FUNCTION_POINT[type]);
     return index >= 0 ? user.splice(index, 1) : '无该权限';
 }
 addPermission('add');
 console.log(checkPermission('edit')); // false
 console.log(user); // [1, 2]
 if(checkPermission('add')) {
     // 执行
     console.log("有添加权限");
 }

使用位操作符

这里使用按位操作符实现,执行效率会比上面更快少了一些查找等操作简洁许多

let user = 1
const FUNCTION_POINT = {
    add: 1 << 1,
    edit: 1 << 2,
    delete: 1 << 3
}

const addPermission = (type) => {
    // 这里是在位上添1 的操作
    user |= FUNCTION_POINT[type];
}

const deletePermission = (type) => {
    // 这里是在位上对比 同1 为0,所以可以作为取消权限操作
    user ^= FUNCTION_POINT[type];
}
addPermission('edit');
console.log(user); // 5
deletePermission('edit');
console.log(user); // 1
addPermission('add');
// 判断是否有权限使用&运算符,全1为1 有0为0
// 有权限会运算后 转十进制是1,没有权限是0
if(user & FUNCTION_POINT.add){
    // 执行
    console.log("有添加权限");
}

我个人认为更好理解上面段代码的方式是:
就是把二进制码中的每一位当作一个状态,不要纠结于这是什么数字,比如下方的权限翻译成成二机制码是这样的

let user = 00001
const FUNCTION_POINT = {
    add: 00010,
    edit: 00100,
    delete: 01000
}

单看位来说,访问权限需要 第一位是1;
添加权限 第二位得是1;
编辑权限第三位得是1;
删除权限第四位得是 1;
二进制码的每一位 0或1都被当做了是否有这个权限

举一个添加权限的例子,就是最开始提到的按位或运算 |

let user = 00001
user | add
翻译一下是
00001
00010
结果:00011

这样就是利用位当作某种状态判断,包括但不限于此次的权限例子

vue3中应用的场景

在vue3源码中也使用到了位操作符PatchFlags去做一些组件类型的判断来达到靶向更新的目的,这里就不说多了
附一下vue3源码使用位操作符的链接,感兴趣的小伙伴可以自行研究
vue3 PatchFlags

你可能感兴趣的:(javascript,javascript,前端,typescript)