JavaScript位运算符先将操作数转为32位有符号整数(ToInt32),再按补码逐位计算,结果转回Number类型;如-1>>>0得4294967295,1<<31得-2147483648。

JavaScript 中的位运算符(如 &、|、^、~、<<、>>、>>>)**不直接操作原始数值本身,而是先将操作数转换为带符号的 32 位整数(two's complement),再按位计算,最后将结果转回 JavaScript 数值类型**。这个隐式转换过程是理解行为的关键。
位运算前的强制类型转换:转为 32 位有符号整数
所有位运算符都会对操作数执行以下步骤:
- 将操作数用
ToInt32抽象操作处理:先转为数字(若非数字则调用Number()),再取模 2³²,然后按 two's complement 解释为 [-2³¹, 2³¹−1] 范围内的有符号整数; - 例如:
ToInt32(3.7)→3,ToInt32(-5.9)→-5,ToInt32(0x100000000)→0(因为 2³² ≡ 0 mod 2³²); -
ToInt32(NaN)、ToInt32(Infinity)、ToInt32(-Infinity)均返回0; - 字符串会先被转为数字再处理,
"15" & 3等价于15 & 3,但"abc" & 3是0 & 3 === 0。
按位计算基于 32 位补码二进制表示
转换后的两个 32 位整数,逐位进行逻辑运算(与、或、异或)或移位(左移、算术右移、无符号右移):
-
&、|、^是逐位布尔运算,结果仍是 32 位整数; -
~x等价于-(x + 1)(因补码下按位取反 = 取负减 1),例如~5→-6; -
x << n:左移n位,右侧补 0,超出 32 位的部分被丢弃; -
x >> n:算术右移,左侧补符号位(保持正负性),如-8 >> 1→-4; -
x >>> n:无符号右移,左侧补 0,结果恒为非负数,-1 >>> 0→4294967295(即 0xFFFFFFFF)。
结果返回为 JavaScript Number 类型
位运算完成后,32 位结果会通过 ToNumber 转回标准的 IEEE 754 double 类型,但值仍等价于该 32 位补码整数:
立即学习“Java免费学习笔记(深入)”;
- 结果可安全参与后续浮点运算,但本身仍是精确整数(只要在 ±2⁵³ 范围内);
- 注意:
1 << 31得到-2147483648(即 0x80000000),不是正数 2147483648 —— 因为最高位是符号位; - 若需无符号 32 位结果(如哈希、掩码),常用
>> 0或>> 0配合Uint32Array视图来显式解释。
常见陷阱与实用提示
实际使用中容易忽略转换细节,导致意外结果:
- 大整数会被截断:
Math.pow(2, 33) | 0→0(因 2³³ 超出 32 位范围); - 小数被截断:
7.9 | 0→7,这常被用作“取整”,但仅适用于安全整数范围; - 负数右移要区分
>>和>>>:前者保留符号,后者强制转为大正数; - 判断奇偶性用
n & 1比n % 2 === 0更快且对负数也一致(-3 & 1 === 1)。









