Signal ledger / designed reading stage
React 中的位运算
位运算在 React 中的实践
Transition band / reading fieldLong-form note2021-12-07
Continue through the ledger
位运算在 React 中的实践
在该文章中我们可以了解,JavaScript 数字精度的问题是由于数据以二进制的形式储存在计算机中。对二进制数据的计算即为位运算符。
在整个 React 源码中,都穿插了位运算的痕迹,以及 ReactFiberLane.js 文件中
&=
对于两个二进制操作数的每个 bit,如果都为 1,则结果为 1,否则为 0。
let currentStatus = 0b1011;
let Processing = 0b0001;
if ((currentStatus & Processing) /** 0b0001 */ === 0) {
// processing
}
可以用来判断是否当前是否具备某种类型
|=
对于两个二进制操作数的每个 bit,如果任一一个是 1,则结果为 1,如果都为 0,则结果为 0。
let currentStatus = 0b0000;
let Processing = 0b0001;
currentStatus = currentStatus | Processing; // 0b0001
可以用来将类型附加到变量
对一个二进制操作数的每个 bit,逐位进行取反操作(0、1 互换)。按位非运算时,任何数字 x 的运算结果都是-(x + 1)。例如,〜-5 运算结果为 4。
let currentStatus = 0b1011;
let Processing = 0b0001;
currentStatus = currentStatus & ~Processing; // 0b1010
可以与 & 结合用于剔除某个类型
export function getHighestPriorityLane(lanes: Lanes): Lane {
return lanes & -lanes;
}
对于 - 符号,由于 Int32 采用补码表示,所以-lanes可以看作: 按位非后加 1 ((~lanes)+1)。
export function includesSomeLane(a: Lanes | Lane, b: Lanes | Lane) {
return (a & b) !== NoLanes;
}
export function isSubsetOfLanes(set: Lanes, subset: Lanes | Lane) {
return (set & subset) === subset;
}
export function intersectLanes(a: Lanes | Lane, b: Lanes | Lane): Lanes {
return a & b;
}
export function mergeLanes(a: Lanes | Lane, b: Lanes | Lane): Lanes {
return a | b;
}
export function removeLanes(set: Lanes, subset: Lanes | Lane): Lanes {
return set & ~subset;
}
export function higherPriorityLane(a: Lane, b: Lane) {
// This works because the bit ranges decrease in priority as you go left.
return a !== NoLane && a < b ? a : b;
}
<< 右移 >>左移操作符 << 将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零。
右移操作符 >> 是左移的逆运算,也就是原数右边(和上面左移相同位置)为基准,整体向右移动,右边超出的位数将会被清除,左边将会补零。
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; // -00000000000000000000000000000101
console.log(a >> b); // 00000000000000000000000000000001
// expected output: 1
console.log(c >> b); // -00000000000000000000000000000010
// expected output: -2