位运算符基本使用
0000 0000 0000 0000 0000 0000 0000 0011 -> 3 1111 1111 1111 1111 1111 1111 1111 1100 -> ~ 3 = -4
左移位<<:各二进位全部左移若干位,高位丢弃,低位补0。
0000 0000 0000 0000 0000 0000 0000 0110 -> 6 0000 0000 0000 0000 0000 0000 0001 1000 -> 6 << 2 = 24
右移位>>:各二进位全部右移若干位,正数高位补0,负数高位补1,低位丢弃
0000 0000 0000 0000 0000 0000 0000 1100 -> 12 0000 0000 0000 0000 0000 0000 0000 0011 -> 12 >> 2 = 3 负数情况: 1111 1111 1111 1111 1111 1111 1111 0100 -> -12 1111 1111 1111 1111 1111 1111 1111 1101 -> -12 >> 2 = -3
无符号右移位>>>:各二进位全部右移若干位,高位补0,低位丢弃。
0000 0000 0000 0000 0000 0000 0000 1100 -> 12 0000 0000 0000 0000 0000 0000 0000 0011 -> 12 >>> 2 = 3 1111 1111 1111 1111 1111 1111 1111 0100 -> -12 0011 1111 1111 1111 1111 1111 1111 1101 -> -12 >> 2 = 1073741821
正数计算负数:
取反后+1
+5:0101 -5:取反1010 最低位+1 = 1011,1011即为二进制的-5
负数倒推正数:同样为取反后+1
在js中位运算的特点
'str' >>> 0; // ===> Number('str') >>> 0 ===> NaN >>> 0 = 0
位掩码
通过位移定义的一组枚举常量, 可以利用位掩码的特性, 快速操作这些枚举产量(增加, 删除, 比较)
const A = 1 << 0; // 0b00000001 const B = 1 << 1; // 0b00000010 const C = 1 << 2; // 0b00000100 属性增加| ABC = A | B | C //0b00000111 属性删除& ~ AB = ABC & ~C //0b00000011 属性比较 AB 当中包含 B: AB & B === B。// AB & B =>0b00000010 ===B,true AB 当中不包含 C: AB & C === 0 // AB & C =>0b00000000 === 0,true
react中的位运算
标记状态
// A上下文 const A = 1; //0001 // B上下文 const B = 2; //0010 // 当前所处上下文 let curContext = 0; // 没有处在上下文的标志 const NoContext = 0; 假设进入A的上下文 curContext |= A; //即curContext=curContext|A =>0001 判断是否处在某一上下文中,结合按位与操作与NoContext // 是否处在A上下文中,这里为true (curContext & A) !== NoContext //curContext & A)=>0001 !==0000,所以为true,表示在A的上下文中 // 是否处在B上下文中,这里为false,和上方同理 (curContext & B) !== NoContext 离开上下文,取出标记进行恢复 // 从当前上下文中移除上下文A curContext &= ~A; //curContext=curContext& ~A,即0001&1110=0000,进行恢复 // 是否处在A上下文中,此处为false (curContext & A) !== NoContext //(curContext & A)为0000
ReactFiberLane.js
//类型定义 export opaque type Lanes = number; export opaque type Lane = number; // 变量定义 export const NoLanes: Lanes = /* */ 0b0000000000000000000000000000000; export const NoLane: Lane = /* */ 0b0000000000000000000000000000000; export const SyncLane: Lane = /* */ 0b0000000000000000000000000000001; export const SyncBatchedLane: Lane = /* */ 0b0000000000000000000000000000010; export const InputDiscreteHydrationLane: Lane = /* */ 0b0000000000000000000000000000100; const InputDiscreteLanes: Lanes = /* */ 0b0000000000000000000000000011000; const InputContinuousHydrationLane: Lane = /* */ 0b0000000000000000000000000100000; const InputContinuousLanes: Lanes = /* */ 0b0000000000000000000000011000000; // ... // ... const NonIdleLanes = /* */ 0b0000111111111111111111111111111; export const IdleHydrationLane: Lane = /* */ 0b0001000000000000000000000000000; const IdleLanes: Lanes = /* */ 0b0110000000000000000000000000000; export const OffscreenLane: Lane = /* */ 0b1000000000000000000000000000000;
getHighestPriorityLanes
function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes { // 判断 lanes中是否包含 SyncLane if ((SyncLane & lanes) !== NoLanes) { return_highestLanePriority = SyncLanePriority; return SyncLane; } // 判断 lanes中是否包含 SyncBatchedLane if ((SyncBatchedLane & lanes) !== NoLanes) { return_highestLanePriority = SyncBatchedLanePriority; return SyncBatchedLane; } // ... // ... 省略其他代码 return lanes; }
getHighestPriorityLane
0b000 0000 0000 0000 0000 0000 0001 0001 function getHighestPriorityLane(lanes) { return lanes & -lanes; } -lanse: lanes 0001 0001 ~lanes 1110 1110 // 第一步 +1 1110 1111 // 第二步 0001 0001 // lanes & 1110 1111 // -lanes ----------- 0000 0001 若lanes为0001 0000 0001 0000 // lanes & 1111 0000 // -lanes ----------- 0001 0000
getLowestPriorityLane
function getLowestPriorityLane(lanes: Lanes): Lane { // This finds the most significant non-zero bit. const index = 31 - clz32(lanes); return index < 0 NoLanes : 1 << index; }
react-reconciler上下文定义
export const NoContext = /* */ 0b0000000; const BatchedContext = /* */ 0b0000001; const EventContext = /* */ 0b0000010; const DiscreteEventContext = /* */ 0b0000100; const LegacyUnbatchedContext = /* */ 0b0001000; const RenderContext = /* */ 0b0010000; const CommitContext = /* */ 0b0100000; export const RetryAfterError = /* */ 0b1000000; // ... // Describes where we are in the React execution stack let executionContext: ExecutionContext = NoContext;
scheduleUpdateOnFiber
// scheduleUpdateOnFiber函数中包含了好多关于executionContext的判断(都是使用位运算) export function scheduleUpdateOnFiber( fiber: Fiber, lane: Lane, eventTime: number, ) { if (root === workInProgressRoot) { // 判断: executionContext 不包含 RenderContext if ( deferRenderPhaseUpdateToNextBatch || (executionContext & RenderContext) === NoContext ) { // ... } } if (lane === SyncLane) { if ( // 判断: executionContext 包含 LegacyUnbatchedContext (executionContext & LegacyUnbatchedContext) !== NoContext && // 判断: executionContext 不包含 RenderContext或CommitContext (executionContext & (RenderContext | CommitContext)) === NoContext ) { // ... } } // ... }
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注源码搜藏网的更多内容!
【JQ】无限滚动条-jquery.infinitescroll.j
query多选下拉框插件 jquery-multiselect(
手机站jQuery自动完成插件autoComplete.js
热门源码