JS中的位运算
·
3min
·
naeco
前言
最近在做项目,有个需求是消息置顶功能,类似于微信聊天里面的置顶。这个功能前端单独做也没问题,但我们需要多端统一状态,所以需要前后台的配合。所以后台需要在每个消息加一个字段表示是否置顶,但我翻文档并没有发现这个字段,后来我抓包发现置顶会返回一个 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 中奇怪的整型,我们很难保证不会出什么差错,所以建议减少使用。