最近在看React的源碼,注意到了一些有意思的細節,好比常常會出現的一下比較和賦值代碼設計
workInProgress.effectTag |= Ref (workInProgress.effectTag & DidCapture) !== NoEffect
對於平時基本上沒怎麼用到過移位運算的我一開始表示這是啥?爲啥要這麼設計?rest
咱們先來看一下,這個effectTag
具體會有那些值code
// 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
,其餘位都是0
,0bxxx
是原生二進制字面量的表示方法orm
那麼回過頭去咱們再看上面兩句表達式源碼
workInProgress.effectTag |= Ref // 也就是 workInProgress.effectTag = workInProgress.effectTag | RefRef
咱們隨便拿兩個值來舉例,好比Placement
和Update
,也就是0b00000000010 | 0b00000000100
那麼獲得的結果是什麼呢?0b00000000110
,也就等於PlacementAndUpdate
。因此這時候你們知道爲何大部分的值1
所在的位置不同了吧,由於其實每一位的1
表明一種屬性,把他們結合在一塊兒就表明有多種屬性,不會有重複。io
一樣的對於第二個表達式form
(workInProgress.effectTag & DidCapture) !== NoEffect
咱們拿Update
和DidCapture
來進行&
操做,那麼獲得的結果就很明顯了,全部位都是0
,因此後期的&
操做是用來判斷在某個變量中是否含有某個屬性的。好比這裏就是判斷workInProgress.effectTag
中是否含有DidCapture
這個屬性。class
這種設計方式我以爲挺有參考意義的,能夠用在相似權限系統上。大概如今不少權限系統已經這麼作了吧,只是我不知道。。。變量
React源碼正在閱讀中,有望一兩個月把全部成果放出來,有興趣的能夠關注我sed