JS中的位操作在实际项目中的应用

前言:

  Linux中的文件管理子系统的权限管理,想必大家都知道:rwx分别代表read(可读),write(可写), execute(可执行,如果是可执行程序的话),其中rxw可以按照数字表示:

  r  -------------  4

  w -------------  2

  x  -------------  1
  如果有可读,可写,可执行权限,则用7表示...
  

  在最近的项目中,就遇到了这样的问题:我们做是IOT的硬件报警设备,现在一共有7种报警类型,每种设备报警的可能有:1种,多种或者0种,后台返回一个10进制数字来表示这种可能,前端需要根据后台返回的数字判断包含的报警。

  其实这个就跟linux文件权限一样,后台用bit位来存储设备报警结果,一共有7种报警类型,8个bit位就够了,每一个bit位对应一种报警类型,如果包含某种报警,对应的位置为1,反之置为0,然后后台将bit转位10进制的数字传给前端。其实表示这7种报警类型常规的做法是:后台为这报警类型alarm字典,将这7种报警类型存入alarm字典中,每一种报警类型是否包含的话用true和false处理,返回给前端的话如下:

  

{
  alarm1: true,
  alarm2: false,
  alarm3: true,
  alarm4: false,
  alarm5: true,
  alarm6: false,
  alarm7: true,
}

  从结果中,前端可以判定设备产生了4中报警:alarm1,alarm3,alarm5,alarm7。。。

  回到我现在的问题中去,前端需要将后台返回的10进制数字转为2进制数字(8个bit位),然后去判断1的位置,如果某一位的值为1,则包含对应的报警. 

  方法一:非CS专业出身笨办法

let type = alarm.toString(2).padStart(8, '0').split('').reverse()
const arr = [] // 用来存储包含的报警类型
for (var i = 0; i < type.length; i++) {
    if (type[b] === '1') {
      switch (i) {
        case 0:
          alarm.push[i]
          break
        case 1:
          alarm.push[i]
          break
        case 2:
          alarm.push[i]
          break
        case 3:
          alarm.push[i]
          break
        case 4:
          alarm.push[i]
          break
        case 5:
          alarm.push[i]
          break
    
        default:
          break
      }
    }
}
console.log(arr.toString()) // 打印出所有的报警类型

  方法二:利用位操作判断(对于js按位操作不熟悉的同学,请自行补充相关知识)

  

const arr = [] // 用来存储包含的报警类型
for (let i = 0; i < 7; i++) {
    if (alarm >> i & 1) {
        arr.push(i)
    }
}
console.log(arr.toString()) // 打印出所有的报警类型

   按照这个实现,虽然看着舒服,但是简洁加执行效率高,还是很帅的。

  最后来说下,我google的实现结果,感觉更好理解:

// 预先定义不同报警类型
const alarm1 = 1;      // 0000 0001
const alarm2 = 1 << 1; // 0000 0010
const alarm3 = 1 << 2; // 0000 0100
const alarm4 = 1 << 3; // 0000 1000
const alarm5 = 1 << 4; // 0001 0000
const alarm6 = 1 << 5; // 0010 0000
const alarm7 = 1 << 6; // 0100 0000


const arr = [] // 用来存储包含的报警类型
const alarm = 7; // 后台返回的10进制数字

// 是否包含alarm1
if (alarm & alarm1) {}

// 是否包含alarm1和alarm2中的任意一个
if (alarm & (alarm1 | alarm2)) {}

// 是否只包含alarm1和alarm2
if (alarm === (alarm1 | alarm2)) {}

// 是否同时包含alarm1和alarm2
if (alarm === (alarm | (alarm1 | alarm2)) ) {}

参考资料:

https://codeburst.io/using-javascript-bitwise-operators-in-real-life-f551a731ff5

原文地址:https://www.cnblogs.com/hanshuai/p/10725402.html