React 中的位运算
位运算符
在该文章中我们可以了解,JavaScript 数字精度的问题是由于数据以二进制的形式储存在计算机中。对二进制数据的计算即为位运算符。
在整个 React 源码中,都穿插了位运算的痕迹,以及 ReactFiberLane.js
文件中
按位与 &
&=
对于两个二进制操作数的每个 bit,如果都为 1,则结果为 1,否则为 0。
let currentStatus = 0b1011let Processing = 0b0001if ((currentStatus & Processing) /** 0b0001 */ === 0) {// processing}
可以用来判断是否当前是否具备某种类型
按位或 |
|=
对于两个二进制操作数的每个 bit,如果任一一个是 1,则结果为 1,如果都为 0,则结果为 0。
let currentStatus = 0b0000let Processing = 0b0001currentStatus = currentStatus | Processing // 0b0001
可以用来将类型附加到变量
按位非 ~
对一个二进制操作数的每个 bit,逐位进行取反操作(0、1 互换)。按位非运算时,任何数字 x 的运算结果都是-(x + 1)。例如,〜-5 运算结果为 4。
let currentStatus = 0b1011let Processing = 0b0001currentStatus = 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 // 00000000000000000000000000000101const b = 2 // 00000000000000000000000000000010console.log(a << b) // 00000000000000000000000000010100// expected output: 20const a = 5 // 00000000000000000000000000000101const b = 2 // 00000000000000000000000000000010const c = -5 // -00000000000000000000000000000101console.log(a >> b) // 00000000000000000000000000000001// expected output: 1console.log(c >> b) // -00000000000000000000000000000010// expected output: -2