js位运算符

43 阅读2分钟

JavaScript 位运算符

运算符名称描述
&AND如果两位都是 1 则设置每位为 1
|OR如果两位之一为 1 则设置每位为 1
^XOR如果两位只有一位为 1 则设置每位为 1
~NOT反转所有位
<<零填充左位移通过从右推入零向左位移,并使最左边的位脱落。
>>有符号右位移通过从左推入最左位的拷贝来向右位移,并使最右边的位脱落。
>>>零填充右位移通过从左推入零来向右位移,并使最右边的位脱落。

实例

操作结果等同于结果
5 & 110101 & 00010001
5 | 150101 | 00010101
5 ^ 140101 ^ 00010100
~ 510~01011010
5 << 1100101 << 11010
5 >> 120101 >> 10010
5 >>> 120101 >>> 10010

JavaScript 使用 32 位按位运算数

JavaScript 将数字存储为 64 位浮点数,但所有按位运算都以 32 位二进制数执行。

在执行位运算之前,JavaScript 将数字转换为 32 位有符号整数。

执行按位操作后,结果将转换回 64 位 JavaScript 数。

上面的例子使用 4 位无符号二进制数。所以 ~ 5 返回 10。

由于 JavaScript 使用 32 位有符号整数,JavaScript 将返回 -6。

00000000000000000000000000000101 (5)

11111111111111111111111111111010 (~5 = -6)

有符号整数使用最左边的位作为减号。

实际应用

vue3源码中,用二进制来标识状态

export enum EffectFlags {
  /**
   * ReactiveEffect only
   */
  ACTIVE = 1 << 0, // 1
  RUNNING = 1 << 1,  // 10
  TRACKING = 1 << 2, // 100
  NOTIFIED = 1 << 3, // 1000
  DIRTY = 1 << 4, // 10000
  ALLOW_RECURSE = 1 << 5, // 100000
  PAUSED = 1 << 6, // 1000000
}
// 1 | 100 = 101 表示同时拥有ACTIVE和TRACKING状态
const flag = EffectFlags.ACTIVE | EffectFlags.TRACKING
// 1000 | 100 = 1100
const flag2 = EffectFlags.NOTIFIED | EffectFlags.TRACKING
// 后续判断时,可以用 & 运算符  
// flag 101 & 1 = 101 > 0
// falg2 1100 & 1 = 0000 === 0 
if(flag & EffectFlags.ACTIVE) {
  // 处于ACTIVE状态
} else {
  // 未处于ACTIVE状态
}

// flag2取消TRACKING状态
// 注意前面其实还有一堆0,上面省略了
// ~100 = 11111011
// 00001100 & 11111011 = 1000
const flag3 = flag2 &= ~EffectFlags.TRACKING