JavaScript 中你不知道的按位运算
个人主页:康师傅前端面馆
位运算直接操作二进制位,适用于整数(JS 中数字会隐式转换为 32 位有符号整数)。以下是核心运算符详解:
一、基础运算符
-
按位与
&
-
规则 :同位置均为
1
时结果为1
-
示例 :权限校验
javascriptconst READ = 0b001; // 1 const WRITE = 0b010; // 2 const EXECUTE = 0b100; // 4 let userPermissions = READ | WRITE; // 0b011 (3) console.log(userPermissions & READ); // 1 (true) console.log(userPermissions & EXECUTE); // 0 (false)
-
-
按位或
|
-
规则 :同位置任一为
1
则结果为1
-
示例 :组合权限
javascriptlet permissions = READ | EXECUTE; // 0b101 (5)
-
-
按位异或
^
-
规则 :同位置不同则为
1
-
示例 :交换变量(无临时变量)
javascriptlet a = 5; // 0b101 let b = 3; // 0b011 a = a ^ b; // 0b110 (6) b = a ^ b; // 0b101 (5) a = a ^ b; // 0b011 (3)
-
-
按位非
~
-
规则 :所有位取反(相当于
-x - 1
) -
示例 :快速取整
javascriptconsole.log(~~3.7); // 3 (等价于 Math.floor)
-
二、位移运算符
-
左移
<<
-
规则 :向左移动指定位数,低位补
0
-
示例 :快速计算 <math xmlns="http://www.w3.org/1998/Math/MathML"> 2 n 2^n </math>2n
javascriptconst power = 1 << 3; // 8 (2^3)
-
-
有符号右移
>>
-
规则:向右移动,保留符号位
-
示例 :负数处理
javascriptconsole.log(-8 >> 2); // -2 (符号位不变)
-
-
无符号右移
>>>
-
规则 :向右移动,高位补
0
(负数会变正) -
示例 :提取 RGB 颜色值
javascriptconst color = 0xFFA07A; // LightSalmon const red = (color >>> 16) & 0xFF; // 255 const green = (color >>> 8) & 0xFF; // 160
-
三、应用场景
1、权限控制系统
传统方案:
javascript
const permissions = {
read: true,
write: false,
execute: true
};
if (permissions.read) { ... } // 对象属性查找
位运算方案:
javascript
const READ = 1, WRITE = 2, EXECUTE = 4;
const userPerm = READ | EXECUTE;
if (userPerm & READ) { ... } // 位运算检查
优势对比:
维度 | 传统方案 | 位运算方案 |
---|---|---|
内存 | 每个权限占独立内存 | 单整数存储所有权限 |
性能 | 属性查找(O(n)) | 位操作(O(1)) |
序列化 | 需完整对象结构 | 单数字即可传输/存储 |
扩展性 | 新增权限需修改结构 | 新增权限只需定义新位 |
2、多状态标志存储
传统方案(数组/对象):
javascript
const flags = [true, false, true, false]; // 存储4个状态
if (flags[0]) { ... } // 数组索引访问
位运算方案:
javascript
const FLAG_A = 1, FLAG_B = 2, FLAG_C = 4;
let state = FLAG_A | FLAG_C; // 存储多个状态
if (state & FLAG_A) { ... } // 位检查
优势对比:
维度 | 传统方案 | 位运算方案 |
---|---|---|
内存 | 每个状态占4-8字节 | 所有状态共享4字节 |
操作 | 需循环遍历 | 单次位操作完成 |
GC压力 | 产生多个对象/数组 | 无额外内存分配 |
3、高性能数值计算
传统数学运算:
javascript
// 浮点数运算(有精度损失风险)
const half = value / 2;
const doubled = value * 2;
位运算优化:
javascript
// 整数运算(无精度问题)
const half = value >> 1; // 右移1位 = ÷2
const doubled = value << 1; // 左移1位 = ×2
性能测试对比(Chrome V8 100万次操作):
javascript
// 乘法:2.8ms
for(let i=0; i<1e6; i++) a = i * 2;
// 位运算:0.9ms (快3倍)
for(let i=0; i<1e6; i++) a = i << 1;
4、颜色值操作
传统方案(字符串操作):
javascript
const color = "#FFA07A";
const red = parseInt(color.substring(1,3), 16); // 字符串截取+转换
位运算方案:
javascript
const color = 0xFFA07A;
const red = (color >>> 16) & 0xFF; // 无符号右移+掩码
优势对比:
维度 | 传统方案 | 位运算方案 |
---|---|---|
性能 | 字符串解析开销大 | 直接内存操作 |
可读性 | 直观但冗长 | 简洁但需理解位操作 |
类型安全 | 需处理非法字符串 | 天然数值类型保证 |
四、注意事项
- 整数范围 :运算结果在
[-2^31, 2^31-1]
之间,超出会截断。 - 可读性:复杂位运算需添加注释说明逻辑。
- 隐式转换:非整数(如浮点数)会先转成 32 位整数再运算。
示例完整代码:GitHub Gist 链接