React源码阅读之:复合类型方案设计

关于React中一些代码设计

最近在看React的源码,注意到了一些有意思的细节,比如经常会出现的一下比较和赋值代码

workInProgress.effectTag |= Ref
(workInProgress.effectTag & DidCapture) !== NoEffect

对于平时基本上没怎么用到过移位运算的我一开始表示这是啥?为啥要这么设计?

我们先来看一下,这个effectTag具体会有那些值

// Don't change these two values. They're used by React Dev Tools.
export const NoEffect = /*              */ 0b00000000000;
export const PerformedWork = /*         */ 0b00000000001;

// You can change the rest (and add more).
export const Placement = /*             */ 0b00000000010;
export const Update = /*                */ 0b00000000100;
export const PlacementAndUpdate = /*    */ 0b00000000110;
export const Deletion = /*              */ 0b00000001000;
export const ContentReset = /*          */ 0b00000010000;
export const Callback = /*              */ 0b00000100000;
export const DidCapture = /*            */ 0b00001000000;
export const Ref = /*                   */ 0b00010000000;
export const Snapshot = /*              */ 0b00100000000;

// Union of all host effects
export const HostEffectMask = /*        */ 0b00111111111;

export const Incomplete = /*            */ 0b01000000000;
export const ShouldCapture = /*         */ 0b10000000000;

这么一看貌似好像有点意思,可以看到大部分的值都只有一位是1,其他位都是00bxxx是原生二进制字面量的表示方法

那么回过头去我们再看上面两句表达式

workInProgress.effectTag |= Ref
// 也就是
workInProgress.effectTag = workInProgress.effectTag | RefRef

我们随便拿两个值来举例,比如PlacementUpdate,也就是0b00000000010 | 0b00000000100那么得到的结果是什么呢?0b00000000110,也就等于PlacementAndUpdate。所以这时候大家知道为什么大部分的值1所在的位置不一样了吧,因为其实每一位的1代表一种属性,把他们结合在一起就代表有多种属性,不会有重复。

同样的对于第二个表达式

(workInProgress.effectTag & DidCapture) !== NoEffect

我们拿UpdateDidCapture来进行&操作,那么得到的结果就很明显了,所有位都是0,所以后期的&操作是用来判断在某个变量中是否含有某个属性的。比如这里就是判断workInProgress.effectTag中是否含有DidCapture这个属性。

这种设计方式我觉得挺有参考意义的,可以用在类似权限系统上。大概现在很多权限系统已经这么做了吧,只是我不知道。。。

React源码正在阅读中,有望一两个月把所有成果放出来,有兴趣的可以关注我

    原文作者:Jokcy
    原文地址: https://segmentfault.com/a/1190000016284033
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞