位运算符 #
一、运算符概述 #
位运算符直接对整数的二进制位进行操作。在处理标志位、权限、颜色值等场景中非常有用。
二、二进制基础 #
2.1 二进制表示 #
typescript
// 十进制转二进制
console.log((10).toString(2)); // "1010"
console.log((255).toString(2)); // "11111111"
// 二进制字面量(ES6+)
const binary = 0b1010; // 10
console.log(binary); // 10
// 八进制字面量
const octal = 0o755; // 493
console.log(octal); // 493
// 十六进制字面量
const hex = 0xff; // 255
console.log(hex); // 255
2.2 32位整数 #
JavaScript位运算符将操作数视为32位整数:
typescript
// 正数:原码表示
// 5 = 00000000000000000000000000000101
// 负数:补码表示
// -5 = 11111111111111111111111111111011
三、按位与(&) #
3.1 基本用法 #
对应位都为1时结果为1,否则为0:
typescript
console.log(5 & 3); // 1
// 5 = 101
// 3 = 011
// -----
// 1 = 001
3.2 判断奇偶 #
typescript
function isEven(n: number): boolean {
return (n & 1) === 0;
}
function isOdd(n: number): boolean {
return (n & 1) === 1;
}
console.log(isEven(4)); // true
console.log(isOdd(5)); // true
3.3 权限检查 #
typescript
const PERMISSION_READ = 1; // 001
const PERMISSION_WRITE = 2; // 010
const PERMISSION_EXECUTE = 4; // 100
function hasPermission(userPermissions: number, permission: number): boolean {
return (userPermissions & permission) === permission;
}
let userPermissions = PERMISSION_READ | PERMISSION_WRITE; // 3
console.log(hasPermission(userPermissions, PERMISSION_READ)); // true
console.log(hasPermission(userPermissions, PERMISSION_EXECUTE)); // false
3.4 掩码操作 #
typescript
// RGB颜色提取
const color = 0xffa500; // 橙色
const red = (color >> 16) & 0xff;
const green = (color >> 8) & 0xff;
const blue = color & 0xff;
console.log(red, green, blue); // 255, 165, 0
四、按位或(|) #
4.1 基本用法 #
对应位有一个为1时结果为1:
typescript
console.log(5 | 3); // 7
// 5 = 101
// 3 = 011
// -----
// 7 = 111
4.2 权限组合 #
typescript
const PERMISSION_READ = 1;
const PERMISSION_WRITE = 2;
const PERMISSION_EXECUTE = 4;
// 组合权限
const admin = PERMISSION_READ | PERMISSION_WRITE | PERMISSION_EXECUTE; // 7
const editor = PERMISSION_READ | PERMISSION_WRITE; // 3
console.log(admin); // 7
console.log(editor); // 3
4.3 向下取整 #
typescript
function toInt(n: number): number {
return n | 0;
}
console.log(toInt(3.7)); // 3
console.log(toInt(-3.7)); // -3
console.log(toInt(3.14)); // 3
五、按位异或(^) #
5.1 基本用法 #
对应位不同时结果为1,相同时为0:
typescript
console.log(5 ^ 3); // 6
// 5 = 101
// 3 = 011
// -----
// 6 = 110
5.2 交换变量 #
typescript
let a = 5;
let b = 3;
a = a ^ b;
b = a ^ b;
a = a ^ b;
console.log(a, b); // 3, 5
5.3 简单加密 #
typescript
function xorEncrypt(text: string, key: number): string {
let result = "";
for (let i = 0; i < text.length; i++) {
result += String.fromCharCode(text.charCodeAt(i) ^ key);
}
return result;
}
const original = "Hello";
const key = 42;
const encrypted = xorEncrypt(original, key);
console.log(encrypted); // 加密后的字符串
const decrypted = xorEncrypt(encrypted, key);
console.log(decrypted); // "Hello"
5.4 找出唯一数 #
typescript
function findSingle(nums: number[]): number {
return nums.reduce((acc, num) => acc ^ num, 0);
}
console.log(findSingle([1, 2, 2, 1, 3])); // 3
console.log(findSingle([4, 1, 2, 1, 2])); // 4
六、按位非(~) #
6.1 基本用法 #
反转所有位:
typescript
console.log(~5); // -6
// 5 = 00000000000000000000000000000101
// ~5 = 11111111111111111111111111111010 (-6的补码)
6.2 公式 #
text
~x = -(x + 1)
typescript
console.log(~0); // -1
console.log(~1); // -2
console.log(~(-1)); // 0
6.3 检查元素是否存在 #
typescript
const arr = [1, 2, 3, 4, 5];
// indexOf返回-1表示不存在
// ~(-1) = 0 (假值)
if (~arr.indexOf(3)) {
console.log("存在"); // 存在
}
if (!~arr.indexOf(6)) {
console.log("不存在"); // 不存在
}
七、左移(<<) #
7.1 基本用法 #
所有位向左移动,右侧补0:
typescript
console.log(5 << 1); // 10
// 5 = 101
// 5 << 1 = 1010 = 10
7.2 乘以2的幂 #
typescript
console.log(5 << 1); // 10 (5 * 2)
console.log(5 << 2); // 20 (5 * 4)
console.log(5 << 3); // 40 (5 * 8)
// 公式:x << n = x * 2^n
7.3 颜色值组合 #
typescript
function rgbToHex(r: number, g: number, b: number): number {
return (r << 16) | (g << 8) | b;
}
console.log(rgbToHex(255, 165, 0).toString(16)); // "ffa500"
八、右移(>>) #
8.1 有符号右移 #
保留符号位,向右移动:
typescript
console.log(10 >> 1); // 5
// 10 = 1010
// 10 >> 1 = 0101 = 5
console.log(-10 >> 1); // -5 (保留符号位)
8.2 除以2的幂 #
typescript
console.log(10 >> 1); // 5 (10 / 2)
console.log(10 >> 2); // 2 (10 / 4)
console.log(10 >> 3); // 1 (10 / 8)
// 公式:x >> n = Math.floor(x / 2^n)
8.3 无符号右移(>>>) #
用0填充左侧:
typescript
console.log(-1 >>> 0); // 4294967295 (32位最大值)
console.log(-1 >>> 1); // 2147483647
// 将有符号数转为无符号数
function toUnsigned(n: number): number {
return n >>> 0;
}
console.log(toUnsigned(-1)); // 4294967295
九、位运算应用 #
9.1 标志位管理 #
typescript
const FLAG_A = 1 << 0; // 1
const FLAG_B = 1 << 1; // 2
const FLAG_C = 1 << 2; // 4
const FLAG_D = 1 << 3; // 8
class Flags {
private flags: number = 0;
set(flag: number): void {
this.flags |= flag;
}
clear(flag: number): void {
this.flags &= ~flag;
}
toggle(flag: number): void {
this.flags ^= flag;
}
has(flag: number): boolean {
return (this.flags & flag) === flag;
}
toString(): string {
return this.flags.toString(2);
}
}
const flags = new Flags();
flags.set(FLAG_A);
flags.set(FLAG_C);
console.log(flags.toString()); // "101"
console.log(flags.has(FLAG_A)); // true
console.log(flags.has(FLAG_B)); // false
flags.toggle(FLAG_B);
console.log(flags.toString()); // "111"
flags.clear(FLAG_A);
console.log(flags.toString()); // "110"
9.2 颜色操作 #
typescript
interface RGB {
r: number;
g: number;
b: number;
}
function hexToRgb(hex: number): RGB {
return {
r: (hex >> 16) & 0xff,
g: (hex >> 8) & 0xff,
b: hex & 0xff
};
}
function rgbToHex(rgb: RGB): number {
return (rgb.r << 16) | (rgb.g << 8) | rgb.b;
}
const orange = 0xffa500;
console.log(hexToRgb(orange)); // { r: 255, g: 165, b: 0 }
const purple = rgbToHex({ r: 128, g: 0, b: 128 });
console.log(purple.toString(16)); // "800080"
9.3 位掩码 #
typescript
const MASK_LOW_BYTE = 0xff;
const MASK_HIGH_BYTE = 0xff00;
function getLowByte(value: number): number {
return value & MASK_LOW_BYTE;
}
function getHighByte(value: number): number {
return (value & MASK_HIGH_BYTE) >> 8;
}
const value = 0x1234;
console.log(getLowByte(value).toString(16)); // "34"
console.log(getHighByte(value).toString(16)); // "12"
9.4 快速数学运算 #
typescript
// 判断是否为2的幂
function isPowerOfTwo(n: number): boolean {
return n > 0 && (n & (n - 1)) === 0;
}
console.log(isPowerOfTwo(4)); // true
console.log(isPowerOfTwo(6)); // false
// 向下取整到2的幂
function floorPowerOfTwo(n: number): number {
let p = 1;
while (p <= n) p <<= 1;
return p >> 1;
}
console.log(floorPowerOfTwo(5)); // 4
console.log(floorPowerOfTwo(17)); // 16
// 绝对值(不用Math.abs)
function abs(n: number): number {
const mask = n >> 31;
return (n ^ mask) - mask;
}
console.log(abs(-5)); // 5
console.log(abs(5)); // 5
十、位运算符优先级 #
| 优先级 | 运算符 | 说明 |
|---|---|---|
| 1 | ~ | 按位非 |
| 2 | << >> >>> | 移位 |
| 3 | & | 按位与 |
| 4 | ^ | 按位异或 |
| 5 | | | 按位或 |
typescript
console.log(1 | 2 & 3); // 3 (&优先级高于|)
console.log((1 | 2) & 3); // 3
console.log(1 << 2 | 3); // 7 (<<优先级高于|)
console.log(1 << (2 | 3)); // 32
十一、总结 #
本章学习了:
- 按位与(&)和权限检查
- 按位或(|)和权限组合
- 按位异或(^)和交换变量
- 按位非(~)和取反
- 左移(<<)和乘法
- 右移(>>、>>>)和除法
- 位运算实际应用
- 运算符优先级
下一章,我们将学习控制流。
最后更新:2026-03-28