最近在看vue3的源码,看到ShapeFlags的定义中有<<符号,一时之间不知道这个是什么,查了下才知道这个是位运算。于是,准备学习一波js中的位运算。
- 左移操作符(<<): 将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零。 需要将数先转成二进制后再进行位移操作
const a = 5; // 00000000000000000000000000000101
const b = 2; // 00000000000000000000000000000010
console.log(a << b); // 00000000000000000000000000010100
// Expected output: 20
- 右移操作符(>>): 将一个操作数按指定移动的位数向右移动,右边移出位被丢弃,左边移出的空位补符号位(最左边那位)。
const a = 5; // 00000000000000000000000000000101
const b = 2; // 00000000000000000000000000000010
const c = -5; // 11111111111111111111111111111011
console.log(a >> b); // 00000000000000000000000000000001
// Expected output: 1
console.log(c >> b); // 11111111111111111111111111111110
// Expected output: -2
- 按位与操作符(&): 在两个操作数对应的二进位都为 1 时,该位的结果值才为 1。
const a = 5; // 00000000000000000000000000000101
const b = 3; // 00000000000000000000000000000011
console.log(a & b); // 00000000000000000000000000000001
// Expected output: 1
- 按位与赋值运算符(&=): 将两个数的二进制进行按位与运算并将结果赋值给变量
let a = 5; // 00000000000000000000000000000101
a &= 3; // 00000000000000000000000000000011
console.log(a); // 00000000000000000000000000000001
// Expected output: 1
- 按位非运算符(~): 将操作数的位反转。会将操作数转化为 32 位的有符号整型。
const a = 5; // 00000000000000000000000000000101
const b = -3; // 11111111111111111111111111111101
console.log(~a); // 11111111111111111111111111111010
// Expected output: -6
console.log(~b); // 00000000000000000000000000000010
// Expected output: 2
- 按位或运算符(|): 其中一个或两个操作数对应的二进制位为 1 时,该位的结果值为 1。
const a = 5; // 00000000000000000000000000000101
const b = 3; // 00000000000000000000000000000011
console.log(a | b); // 00000000000000000000000000000111
// Expected output: 7
- 按位或赋值运算符(|=): 使用两个操作数的二进制表示,对它们执行按位或运算并将结果分配给变量。
let a = 5; // 00000000000000000000000000000101
a |= 3; // 00000000000000000000000000000011
console.log(a); // 00000000000000000000000000000111
// Expected output: 7
- 按位异或运算符(^): 在两个操作数有且仅有一个对应的二进制位为 1 时,该位的结果值为 1。
const a = 5; // 00000000000000000000000000000101
const b = 3; // 00000000000000000000000000000011
console.log(a ^ b); // 00000000000000000000000000000110
// Expected output: 6
- 按位异或运算符(^=): 使用二进制表示操作数,进行一次按位异或操作并赋值。
let a = 5; // 00000000000000000000000000000101
a ^= 3; // 00000000000000000000000000000011
console.log(a); // 00000000000000000000000000000110
// Expected output: 6
因为位操作符都需要先将数字转成二进制的,而我们日常接触的都是十进制的,JS原生也提供了这种进制转换的方法。
- 十进制转二进制
a = 5;
// 将十进制转成给定长度的二进制
a.toString(2).padStart(32, 0) // 00000000000000000000000000000101
- 二进制转十进制
a = 100;
parseInt(a, 2); // 第二个参数表示给定数字的基数,取值范围为2~36,默认为10
注: 这两个方法对负数的处理有问题,因为它们会保留负数的符号而不是将第一位的符号位设置为1。