位运算直接操作二进制位,是 JavaScript 中最快的操作之一——但也是最容易被忽视的“隐藏技能”。
在日常开发中,我们很少直接使用位运算。但在性能敏感场景(如游戏引擎、图形处理、状态管理)中,它却能带来极致效率。今天,我们就来系统梳理 JavaScript 中的 7 个位运算符,从原理到实战,一文掌握!
📌 核心前提:位运算只对 32 位整数生效
尽管 JavaScript 所有数字都以 64 位浮点数 存储,但执行位运算时,会自动转为 32 位带符号整数,运算结果也返回 32 位整数。
1.9 | 0 // → 1(小数部分被截断)
-2.9 | 0 // → -2
2147483649 | 0 // → -2147483647(溢出!)
✅ 利用此特性,可快速取整:
function toInt32(x) {
return x | 0;
}
⚠️ 注意:超过 ±2³¹−1 的数会溢出,慎用!
🔧 七大位运算符详解
1️⃣ 按位或(|)
规则:两位中至少一个为 1,结果为 1。
0 | 3 // → 3 (00 | 11 → 11)
2.9 | 0 // → 2(取整)
✅ 用途:快速取整、组合标志位(见后文“开关”应用)
2️⃣ 按位与(&)
规则:两位都为 1,结果才为 1。
0 & 3 // → 0 (00 & 11 → 00)
5 & 4 // → 4 (101 & 100 → 100)
✅ 用途:检测某一位是否开启(权限判断)
3️⃣ 按位非(~)
规则:每一位取反(0→1,1→0)。
~3 // → -4
~-3 // → 2
~~3.9 // → 3(双非取整,速度极快!)
💡 记忆技巧:~n === -(n + 1)
✅ 用途:快速取整(~~x)、字符串/布尔值转整数
4️⃣ 按位异或(^)
规则:两位不同则为 1,相同则为 0。
0 ^ 3 // → 3 (00 ^ 11 → 11)
12.9 ^ 0 // → 12(取整)
🔥 神技:不借助临时变量交换两个数
let a = 10, b = 99;
a ^= b; b ^= a; a ^= b;
// 现在 a=99, b=10
✅ 用途:加密、校验、状态切换
5️⃣ 左移(<<)
规则:二进制向左移 n 位,低位补 0,相当于 × 2ⁿ。
4 << 1 // → 8 (100 → 1000)
-4 << 1 // → -8
13.5 << 0 // → 13(取整)
🎨 实战:RGB 转 HEX 颜色
const rgb2hex = (r, g, b) =>
'#' + ((1 << 24) + (r << 16) + (g << 8) + b)
.toString(16)
.substr(1);
rgb2hex(186, 218, 85); // → "#bada55"
6️⃣ 有符号右移(>>)
规则:向右移 n 位,高位补符号位(正数补 0,负数补 1),相当于 ÷ 2ⁿ 向下取整。
4 >> 1 // → 2
-4 >> 1 // → -2
21 >> 2 // → 5(21 ÷ 4 = 5.25 → 5)
✅ 用途:快速整除 2 的幂
7️⃣ 无符号右移(>>>)
规则:向右移 n 位,高位一律补 0,结果恒为正数。
-4 >>> 1 // → 2147483646
-1 >>> 0 // → 4294967295(即 2³² - 1)
✅ 用途:查看负数的原始二进制表示、转为无符号整数
🎯 实战应用:用位运算实现“开关系统”
假设一个对象有多个布尔状态(如权限、功能开关),传统做法需多个变量。而位运算只需一个数字!
步骤 1:定义开关常量(每位代表一个开关)
const FLAG_A = 1; // 0001
const FLAG_B = 2; // 0010
const FLAG_C = 4; // 0100
const FLAG_D = 8; // 1000
步骤 2:组合开关(按位或)
let flags = FLAG_A | FLAG_C; // 0101 → 开启 A 和 C
步骤 3:检测是否开启某开关(按位与)
if (flags & FLAG_C) {
console.log('C 已开启');
}
步骤 4:切换开关状态(按位异或)
flags ^= FLAG_B; // 如果 B 关,则开;如果开,则关
步骤 5:关闭某些开关(按位与 + 掩码取反)
flags &= ~FLAG_A; // 关闭 A
💡 这种模式广泛用于:游戏技能状态、用户权限系统、Canvas 渲染选项等。
⚠️ 使用建议
- ✅ 适合场景:性能关键路径、状态压缩、底层协议解析
- ❌ 避免场景:业务逻辑复杂处(可读性差)
- 🔒 替代方案:现代 JS 可用
Set或位域枚举提升可读性
🌟 结语
位运算虽“古老”,却是性能优化的利器。理解它,不是为了炫技,而是在需要时,多一种高效解决问题的工具。
真正的高手,既写得出优雅的 Promise,也玩得转底层的 Bit。















暂无评论内容