你可能在代码里见过类似 a <<= 2
或者 b >>= 1
这样的写法,看起来像数学里的「大于等于」符号被拆开了?其实这是 JavaScript 中的移位赋值运算符。它的作用听起来有点玄乎——通过「移动二进制位的位置」来快速完成计算。
别被「二进制位」「移位」这些词吓到,我们用生活中的例子一步步拆解,保证你看完能直接上手用。
先搞懂:什么是「移位运算」?
要理解「移位赋值」,得先明白「移位运算」。计算机的世界本质是二进制的(0和1),每个数字在内存里都是一串由0和1组成的「二进制串」。比如:
数字5的二进制是
101
(对应十进制:1×4 + 0×2 + 1×1 = 5)数字8的二进制是
1000
(对应十进制:1×8 + 0×4 + 0×2 + 0×1 = 8)
移位运算,就是把这串二进制数字整体往左或往右「挪位置」,挪完后得到的新二进制串再转成十进制。
比如:
左移1位:把二进制串整体往左挪1位,右边空出的位置补0。
例:5(
101
)左移1位 →1010
(对应十进制10)右移1位(有符号右移):把二进制串整体往右挪1位,左边空出的位置补符号位(正数补0,负数补1)。
例:8(
1000
)右移1位 →100
(对应十进制4)
这时候你会发现:左移1位相当于乘以2,右移1位相当于除以2(取整数部分)。这是移位运算的核心规律,也是它高效的秘密——计算机直接操作二进制位,比普通乘法除法更快。
移位赋值运算符:挪完位置直接存回去
「移位赋值运算符」就是把「移位运算」的结果直接赋值给原来的变量,相当于「挪位置+保存」一步完成。JavaScript 中有3种常见的移位赋值运算符:
这里的 b
是「要移动的位数」,必须是0到31之间的整数(因为JavaScript的数字用64位存储,但位运算只处理32位)。
一个一个看:具体怎么用?
1. <<=
:左移赋值——快速算「乘以2的n次方」
左移赋值运算符 <<=
相当于把变量的值左移 b
位,再存回原变量。根据之前的规律,左移 b
位等于乘以 2^b
(2的b次方)。
例子:
let num = 3; // 二进制是 00000000 00000000 00000000 00000011(32位简化)
num <<= 2; // 左移2位,相当于 3 × 2² = 3×4=12
console.log(num); // 输出12(二进制变成 00000000 00000000 00000000 00001100)
适用场景:需要快速计算一个数乘以2的多次方时(比如处理图片像素大小、内存容量单位转换)。
2. >>=
:有符号右移赋值——快速算「除以2的n次方(取整)」
有符号右移赋值运算符 >>=
相当于把变量的值有符号右移 b
位,再存回原变量。有符号右移时,左边空出的位置补符号位(正数补0,负数补1),因此结果相当于「除以 2^b
后向下取整」。
正数例子:
let positive = 20; // 二进制是 00000000 00000000 00000000 00010100
positive >>= 2; // 右移2位,相当于 20 ÷ 2² = 20÷4=5(取整)
console.log(positive); // 输出5(二进制变成 00000000 00000000 00000000 00000101)
负数例子(关键!):
let negative = -8; // 二进制补码表示为 11111111 11111111 11111111 11111000(补码是负数的二进制表示方式)
negative >>= 2; // 有符号右移2位,左边补符号位(负数补1)
// 计算过程:原二进制右移2位 → 11111111 11111111 11111111 11111110(补码)
// 转回十进制负数:-2(因为补码11111110对应的原码是10000010,即-2)
console.log(negative); // 输出-2
适用场景:需要快速计算一个数除以2的多次方并取整时(比如分页计算、数据分组)。
3. >>>=
:无符号右移赋值——把负数当正数处理
无符号右移赋值运算符 >>>=
和 >>=
类似,但有个关键区别:无论原数是正还是负,右移时左边都补0。因此,负数经过无符号右移后会变成一个很大的正数(因为补0后二进制串被当作正数处理)。
例子:
let num = -8; // 二进制补码:11111111 11111111 11111111 11111000
num >>>= 2; // 无符号右移2位,左边补0 → 00111111 11111111 11111111 11111110
// 转回十进制:这个二进制串是很大的正数(4294967294)
console.log(num); // 输出4294967294
适用场景:处理需要忽略符号位的二进制数据(比如解析网络协议、处理图像像素的二进制位)。
总结:什么时候用移位赋值?
移位赋值运算符的核心优势是高效——计算机直接操作二进制位,比普通乘法除法更快。但它的问题也很明显:可读性差,不是有经验的开发者很难一眼看懂。
所以在实际开发中,除非你需要:
处理底层二进制数据(如网络协议、文件格式);
对性能有极高要求(如游戏引擎、高频交易计算);
理解他人遗留的位操作代码;
否则,普通的乘法(*
)和除法(/
)会更直观。
不过,知道这些运算符的存在,至少能让你在看别人的代码时不至于一头雾水——毕竟,编程的世界里,「看懂」有时候比「会写」更重要。
评论