JS中的位运算

# 前言

最近在做项目,有个需求是消息置顶功能,类似于微信聊天里面的置顶。这个功能前端单独做也没问题,但我们需要多端统一状态,所以需要前后台的配合。所以后台需要在每个消息加一个字段表示是否置顶,但我翻文档并没有发现这个字段,后来我抓包发现置顶会返回一个status为1063,而不置顶会返回1059。后面和后台确认了一下才知道他们用status这个字段表示了好几种状态,每一个状态分别用二进制的一位来代表,置顶这个状态就用了第三位,所以同一个消息置顶和不置顶status的值会相差4(2^2=4)。知道什么意思就好办了,嗯,首先先把status用toString(2)转化为二进制,然后再提取第三位来判断。等等,这样做实在太麻烦了,有没有简单一点的方法呢?有的,这时候位运算就派上用场了,我们只需要写一行代码就可以判断了:

  if ( (status & 4) !== 0 ) {
    ...
  }

&叫做按位与运算符,和&&很像,只有两个操作数的比特位都是1时才返回1。所以只要第三位是0,不管status有啥,与4进行按位与都会返回0。同样的原理,我们让status分别和2^(n-1)进行按位与,就可以提取出每一位的状态,这样用一个字段就可以表示全部的状态。 做完这个需求后,我又在网上看了一些文章,发现了位运算在JS中的一些妙用:

# 向下取整(1)

const n = 7.5
Math.floor(n)   // 7
7.5 | 0         // 7

# 向下取整(2)

const n = 7.5
Math.floor(n)   // 7
~~n         // 7

# 0和1切换

0 ^ 1       // 0
1 ^ 1       // 1

# 乘法(左移一位相当于乘2)

2 << 1      //4
3 << 1      //6
4 << 1      //8

# 后续

暂时想到的只有这么多,以后找到再补充。不过提醒一句,虽然位运算符看起来很简洁,但带来的是可读性的大大降低,再加上JS中奇怪的整型,我们很难保证不会出什么差错,所以建议减少使用。