欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳細(xì)聊聊React源碼中的位運(yùn)算技巧

 更新時(shí)間:2021年10月12日 11:40:26   作者:魔術(shù)師卡頌  
眾所周知在React中,主要用到3種位運(yùn)算符 —— 按位與、按位或、按位非,下面這篇文章主要給大家介紹了關(guān)于React源碼中的位運(yùn)算技巧的相關(guān)資料,需要的朋友可以參考下

前言

這兩年有不少朋友和我吐槽React源碼,比如:

  • 調(diào)度器為什么用小頂堆這種數(shù)據(jù)結(jié)構(gòu),直接用數(shù)組不行?
  • 源碼里各種單向鏈表、環(huán)狀鏈表,直接用數(shù)組不行?
  • 源碼里各種位運(yùn)算,有必要么?

作為業(yè)務(wù)依賴的框架,為了提升一點(diǎn)點(diǎn)運(yùn)行時(shí)性能,React從不吝惜將源碼寫的很復(fù)雜。

在涉及狀態(tài)、標(biāo)記位、優(yōu)先級操作的地方大量使用了位運(yùn)算。
本文會講解其中比較有代表性的部分。學(xué)到之后,當(dāng)遇到類似場景時(shí)露一手,你就是業(yè)務(wù)線最靚的仔。

幾個(gè)常用位運(yùn)算

在JS中,位運(yùn)算的操作數(shù)會先轉(zhuǎn)換為Int32(32位有符號整型),執(zhí)行完位運(yùn)算會Int32對應(yīng)浮點(diǎn)數(shù)。

在React中,主要用到3種位運(yùn)算符 —— 按位與、按位或、按位非。

按位與(&)

對于兩個(gè)二進(jìn)制操作數(shù)的每個(gè)bit,如果都為1,則結(jié)果為1,否則為0。

舉個(gè)例子,計(jì)算3 & 2,首先將操作數(shù)轉(zhuǎn)化為Int32:

// 3對應(yīng)的 Int32
0b000 0000 0000 0000 0000 0000 0000 0011 
// 2對應(yīng)的 Int32
0b000 0000 0000 0000 0000 0000 0000 0010 

為了直觀,我們排除前面的0,只保留最后8位(實(shí)際參與計(jì)算的應(yīng)該是32位):

  0000 0011
& 0000 0010
-----------
  0000 0010

所以3 & 2計(jì)算結(jié)果轉(zhuǎn)化為浮點(diǎn)數(shù)后為2。

按位或(|)

對于兩個(gè)二進(jìn)制操作數(shù)的每個(gè)bit,如果都為0,則結(jié)果為0,否則為1。

計(jì)算10 | 3:

  0000 1010
| 0000 0011
-----------
  0000 1011

計(jì)算結(jié)果轉(zhuǎn)化為浮點(diǎn)數(shù)后為11。

按位非(~)

對一個(gè)二進(jìn)制操作數(shù)的每個(gè)bit,逐位進(jìn)行取反操作(0、1互換)

對于~3,將3轉(zhuǎn)化為Int32后逐位取反:

// 3對應(yīng)的 Int32
0b000 0000 0000 0000 0000 0000 0000 0011 
// 逐位取反
0b111 1111 1111 1111 1111 1111 1111 1100

計(jì)算結(jié)果轉(zhuǎn)化為浮點(diǎn)數(shù)后為-4。

如果你對這個(gè)結(jié)果有疑惑,可以去了解補(bǔ)碼相關(guān)知識

讓我們從易到難,看看位運(yùn)算在React中的應(yīng)用。

標(biāo)記狀態(tài)

React源碼內(nèi)部有多個(gè)上下文環(huán)境,在執(zhí)行函數(shù)時(shí)經(jīng)常需要判斷當(dāng)前處在哪個(gè)上下文環(huán)境中。

假設(shè)共有三種上下文情況:

// A上下文
const A = 1;
// B上下文
const B = 2;
// 沒有處在上下文
const NoContext = 0;

當(dāng)進(jìn)入某個(gè)上下文時(shí),可以使用按位或操作標(biāo)記進(jìn)入:

// 當(dāng)前所處上下文
let curContext = 0;

// 進(jìn)入A上下文
curContext |= A;

我們用8位二進(jìn)制舉例(同樣,實(shí)際應(yīng)該是Int32,這里是為了簡化),curContext與A執(zhí)行按位或操作:

  0000 0000  // curContext
| 0000 0001  // A
-----------
  0000 0001

此時(shí)可以結(jié)合按位與操作與NoContext來判斷是否處在某一上下文中:

// 是否處在A上下文中 true
(curContext & A) !== NoContext

// 是否處在B上下文中 false
(curContext & B) !== NoContext

離開某上下文后,結(jié)合按位與、按位非移除標(biāo)記:

// 從當(dāng)前上下文中移除上下文A
curContext &= ~A;

// 是否處在A上下文中 false
(curContext & A) !== NoContext

curContext與~A執(zhí)行按位與操作:

  0000 0001  // curContext
& 1111 1110  // ~A
-----------
  0000 0000

即從curContext中移除A。

當(dāng)業(yè)務(wù)中需要同時(shí)處理多個(gè)狀態(tài)時(shí),可以使用如上位運(yùn)算技巧。

優(yōu)先級計(jì)算

在React中,不同情況下調(diào)用this.setState觸發(fā)的更新會擁有不同優(yōu)先級。優(yōu)先級之間的比較、挑選同樣使用了位運(yùn)算。
具體來說,React中用31個(gè)bit位保存更新(之所以是31而不是32是因?yàn)镮nt32的最高位是符號位,不保存具體的數(shù))。

處在越低bit位的更新優(yōu)先級越高(越需要優(yōu)先處理)。

舉個(gè)例子,假設(shè)當(dāng)前應(yīng)用存在2個(gè)更新:

0b000 0000 0000 0000 0000 0000 0001 0001

其中第1位的更新優(yōu)先級最高(需要同步處理),第5位為默認(rèn)優(yōu)先級。

React經(jīng)常需要找出當(dāng)前最高優(yōu)先級的更新在哪一位(如上例子中在第一位),方法如下:

function getHighestPriorityLane(lanes) {
  return lanes & -lanes;
}

解釋下,由于Int32采用補(bǔ)碼表示,所以-lanes可以看作如下兩步操作:

  1. lanes取反(~lanes)
  2. 加1

為了直觀,用8位表示:

lanes  0001 0001
~lanes 1110 1110 // 第一步
+1     1110 1111 // 第二步

則lanes & -lanes如下:

  0001 0001 // lanes  
& 1110 1111 // -lanes
-----------
  0000 0001

取到的就是第一位(已有更新中最高的優(yōu)先級)。

總結(jié)

雖然業(yè)務(wù)中不常使用位操作,但在特定場景下位操作時(shí)很方便、高效的方式。

這波操作你愛了么?

到此這篇關(guān)于React源碼中位運(yùn)算技巧的文章就介紹到這了,更多相關(guān)React源碼中位運(yùn)算技巧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Modal.confirm是否違反了React模式分析

    Modal.confirm是否違反了React模式分析

    這篇文章主要為大家介紹了Modal.confirm是否違反了React模式分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • react+react-beautiful-dnd實(shí)現(xiàn)代辦事項(xiàng)思路詳解

    react+react-beautiful-dnd實(shí)現(xiàn)代辦事項(xiàng)思路詳解

    這篇文章主要介紹了react+react-beautiful-dnd實(shí)現(xiàn)代辦事項(xiàng),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • 淺談React 屬性和狀態(tài)的一些總結(jié)

    淺談React 屬性和狀態(tài)的一些總結(jié)

    下面小編就為大家?guī)硪黄獪\談React 屬性和狀態(tài)的一些總結(jié)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-11-11
  • 通過示例源碼解讀React首次渲染流程

    通過示例源碼解讀React首次渲染流程

    這篇文章主要為大家通過示例源碼解讀React的首次渲染流程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • React中使用async validator進(jìn)行表單驗(yàn)證的實(shí)例代碼

    React中使用async validator進(jìn)行表單驗(yàn)證的實(shí)例代碼

    react上進(jìn)行表單驗(yàn)證是很繁瑣的,在這里使用async-validator處理起來就變的很方便了,接下來通過本文給大家介紹React中使用async validator進(jìn)行表單驗(yàn)證的方法,需要的朋友可以參考下
    2018-08-08
  • React?數(shù)據(jù)共享useContext的實(shí)現(xiàn)

    React?數(shù)據(jù)共享useContext的實(shí)現(xiàn)

    本文主要介紹了React?數(shù)據(jù)共享useContext的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • React父組件如何調(diào)用子組件的方法推薦

    React父組件如何調(diào)用子組件的方法推薦

    在React中,我們經(jīng)常在子組件中調(diào)用父組件的方法,一般用props回調(diào)即可,這篇文章主要介紹了React父組件如何調(diào)用子組件的方法推薦,需要的朋友可以參考下
    2023-11-11
  • React Native自定義標(biāo)題欄組件的實(shí)現(xiàn)方法

    React Native自定義標(biāo)題欄組件的實(shí)現(xiàn)方法

    今天講一下如何實(shí)現(xiàn)自定義標(biāo)題欄組件,我們都知道RN有一個(gè)優(yōu)點(diǎn)就是可以組件化,在需要使用該組件的地方直接引用并傳遞一些參數(shù)就可以了,這種方式確實(shí)提高了開發(fā)效率。對React Native自定義標(biāo)題欄組件的實(shí)現(xiàn)方法感興趣的朋友參考下
    2017-01-01
  • React函數(shù)式組件的性能優(yōu)化思路詳解

    React函數(shù)式組件的性能優(yōu)化思路詳解

    這篇文章主要介紹了React函數(shù)式組件的性能優(yōu)化思路詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 在react中使用highlight.js將頁面上的代碼高亮的方法

    在react中使用highlight.js將頁面上的代碼高亮的方法

    本文通過 highlight.js 庫實(shí)現(xiàn)對文章正文 HTML 中的代碼元素自動添加語法高亮,具有一定的參考價(jià)值,感興趣的可以了解一下
    2022-01-01

最新評論