Vue3源碼學習7-PatchFlags使用位算符

文章目錄

  • 前言
    • ? 一、基礎知識:什么是二進制?
    • ? 二、位運算的基本操作
    • ? 三、左移運算 `<<`
    • ? 四、實際用途:如何用于狀態標記(PatchFlags)
    • ? 五、組合多個狀態標記
    • ? 六、小結口訣(記憶)
    • ? 一、語法含義
    • ? 二、在 `PatchFlags` 中的作用
      • 示例說明:
    • ? 三、這樣寫的好處
      • 1. **便于使用位運算組合多個標記**
      • 2. **檢查時快速**
      • 3. **性能極高**
    • ? 四、實際示例
    • ? 五、小結一句話(適合面試)
  • 補充
    • ? 1. **權限管理(權限位)**
    • ? 2. **日志級別控制(Logging Flags)**
    • ? 3. **狀態管理(多個狀態疊加)**
    • ? 4. **DOM 元素樣式/行為控制**
    • ? 5. **游戲開發中的狀態控制**
    • 🧠 小結口訣(記憶):


前言

vue3在編譯相關的源碼中:有這一段

export enum PatchFlags {/*** Indicates an element with dynamic textContent (children fast path)*/TEXT = 1,/*** Indicates an element with dynamic class binding.*/CLASS = 1 << 1,/*** Indicates an element with dynamic style* The compiler pre-compiles static string styles into static objects* + detects and hoists inline static objects* e.g. style="color: red" and :style="{ color: 'red' }" both get hoisted* as:* 
js* const style = { color: 'red' }* render() { return e('div', { style }) }**/STYLE = 1 << 2,
// 省略其他

這樣用有什么好處?我們先從最基本的二進制和位運算概念講起,再理解 1 << n 的用法,最后回到 PatchFlags


? 一、基礎知識:什么是二進制?

計算機底層只認識 0 和 1,我們用“二進制”來表示:

十進制二進制
10001
20010
40100
81000

? 二、位運算的基本操作

運算符含義示例(十進制)示例(二進制)結果
&按位與5 & 30101 & 0011 = 00011
``按位或5 | 30101 | 0011 = 01117
<<左移1 << 20001 → 01004
>>右移4 >> 10100 → 00102

? 三、左移運算 <<

左移就是把二進制整體向左“推”一位,后面補 0。

1      => 二進制是 0001
1 << 1 =>0010 => 十進制 2
1 << 2 =>0100 => 十進制 4
1 << 3 =>1000 => 十進制 8

所以可以理解成:

1 << n === 2 的 n 次方

? 四、實際用途:如何用于狀態標記(PatchFlags)

Vue 3 中通過這個方式給每種類型的“變更”分配唯一標志位:

export enum PatchFlags {TEXT = 1,         // 0001 => 1CLASS = 1 << 1,   // 0010 => 2STYLE = 1 << 2,   // 0100 => 4PROPS = 1 << 3,   // 1000 => 8
}

每個標志只占一位,組合時不會沖突。


? 五、組合多個狀態標記

// 組合標記
const patchFlag = PatchFlags.CLASS | PatchFlags.STYLE // 2 | 4 = 6 => 0110// 檢查是否包含 PatchFlags.STYLE
if (patchFlag & PatchFlags.STYLE) {console.log('需要更新 style')
}

因為:

patchFlag = 0110
STYLE     = 0100
&         = 0100 → 非 0,說明包含

? 六、小結口訣(記憶)

技術點口訣
1 << n就是 2 的 n 次方,用來生成唯一的二進制標志位
`` 或運算多個標志合并為一個 patchFlag
& 與運算判斷某個標志是否存在于 patchFlag 中(非 0 表示存在)

在這里插入圖片描述

這是 TypeScript(或 JavaScript)中的位運算符 <<,表示左移位運算(left shift)


? 一、語法含義

1 << 1  // 結果是 2
1 << 2  // 結果是 4
1 << 3  // 結果是 8

換句話說:

1 << n === 2?

? 二、在 PatchFlags 中的作用

Vue 3 的編譯器使用 PatchFlags 來標記 虛擬 DOM 節點有哪些動態變化的部分

示例說明:

export enum PatchFlags {TEXT = 1,         // 0001CLASS = 1 << 1,   // 0010 => 2STYLE = 1 << 2,   // 0100 => 4PROPS = 1 << 3,   // 1000 => 8// 依此類推...
}

? 三、這樣寫的好處

1. 便于使用位運算組合多個標記

  • 可以用按位或(|)組合多個 patch 標志:

    const patchFlag = PatchFlags.TEXT | PatchFlags.CLASS
    // 即 0001 | 0010 = 0011 => patchFlag = 3
    

2. 檢查時快速

  • Vue 更新虛擬 DOM 時可以通過按位與(&)檢查:

    if (patchFlag & PatchFlags.CLASS) {// 有 CLASS 需要處理
    }
    

3. 性能極高

  • 位運算是底層最輕量的運算方式之一,比數組查找或對象比較快很多
  • 避免使用多個 boolean 類型判斷。

? 四、實際示例

const patchFlag = PatchFlags.CLASS | PatchFlags.STYLE; // 2 | 4 = 6if (patchFlag & PatchFlags.CLASS) {console.log('需要更新 class')
}if (patchFlag & PatchFlags.STYLE) {console.log('需要更新 style')
}

? 五、小結一句話(適合面試)

Vue 3 使用位移表達式(如 1 << n)生成 2 的冪,實現 PatchFlags 的唯一性標識、位掩碼組合、按位判斷等優化邏輯,在虛擬 DOM diff 過程中既高效又靈活。


補充

非常好!這種“位運算 + 標志位”的方式是一種經典的性能優化技巧,不僅用于 Vue 的 PatchFlags,還廣泛應用于許多實際場景中,比如權限控制、狀態管理、日志等級控制等。

下面我列出幾個常見 應用場景 并配上示例說明:


? 1. 權限管理(權限位)

場景:一個用戶可能擁有多個權限,如讀、寫、刪、改等。

// 權限定義(每個權限占一位)
export enum Permission {READ  = 1 << 0,  // 0001 = 1WRITE = 1 << 1,  // 0010 = 2DELETE = 1 << 2, // 0100 = 4UPDATE = 1 << 3  // 1000 = 8
}// 設置權限(讀 + 寫)
let userPermission = Permission.READ | Permission.WRITE  // 0011 = 3// 檢查是否有寫權限
if (userPermission & Permission.WRITE) {console.log('有寫權限')
}

優點:節省空間(用一個整數存多個權限),判斷權限快(位運算)。


? 2. 日志級別控制(Logging Flags)

enum LogLevel {ERROR = 1 << 0,WARN  = 1 << 1,INFO  = 1 << 2,DEBUG = 1 << 3
}// 當前啟用的日志級別(錯誤 + 警告)
const activeLogLevel = LogLevel.ERROR | LogLevel.WARNfunction log(msg: string, level: LogLevel) {if (activeLogLevel & level) {console.log(`[${LogLevel[level]}]`, msg)}
}log('Something wrong', LogLevel.ERROR) // 會輸出
log('Just info', LogLevel.INFO)        // 不會輸出

? 3. 狀態管理(多個狀態疊加)

場景:表示一個任務的多個狀態(如:初始化、加載中、完成、失敗)

enum TaskStatus {INIT     = 1 << 0,LOADING  = 1 << 1,SUCCESS  = 1 << 2,FAILED   = 1 << 3
}let currentStatus = TaskStatus.INIT | TaskStatus.LOADING// 判斷是否正在加載
if (currentStatus & TaskStatus.LOADING) {console.log('任務加載中')
}

? 4. DOM 元素樣式/行為控制

例如用于判斷是否啟用多個 UI 特效:

enum UIFlags {HIGHLIGHT = 1 << 0,BLINK     = 1 << 1,SHADOW    = 1 << 2
}let elementFlags = UIFlags.HIGHLIGHT | UIFlags.SHADOWif (elementFlags & UIFlags.HIGHLIGHT) {// 給元素加高亮
}

? 5. 游戲開發中的狀態控制

例如角色可能處于多種狀態:跳躍、攻擊、被擊中等。

enum PlayerState {IDLE    = 1 << 0,JUMPING = 1 << 1,ATTACK  = 1 << 2,HURT    = 1 << 3
}let currentState = PlayerState.JUMPING | PlayerState.ATTACK// 檢查是否正在攻擊
if (currentState & PlayerState.ATTACK) {console.log('攻擊中')
}

🧠 小結口訣(記憶):

“一個數,多個狀態;左移位,值唯一;按位或,組合用;按位與,判斷快。”


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/78830.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/78830.shtml
英文地址,請注明出處:http://en.pswp.cn/web/78830.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在 Vue 2 中使用 qrcode 庫生成二維碼

&#x1f31f; 前言 歡迎來到我的技術小宇宙&#xff01;&#x1f30c; 這里不僅是我記錄技術點滴的后花園&#xff0c;也是我分享學習心得和項目經驗的樂園。&#x1f4da; 無論你是技術小白還是資深大牛&#xff0c;這里總有一些內容能觸動你的好奇心。&#x1f50d; &#x…

電子電器架構 --- 網關釋放buffer的必要性

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 鈍感力的“鈍”,不是木訥、遲鈍,而是直面困境的韌勁和耐力,是面對外界噪音的通透淡然。 生活中有兩種人,一種人格外在意別人的眼光;另一種人無論…

Java中Stream、File、方法遞歸

文章目錄 十五、Stream流、File、方法遞歸1、Stream1.1 什么是Stream1.2 獲取Stream流1.3 Stream流常見的中間方法1.3 Stream流常見的終結方法1.4 收集Stream流 2、File、IO流&#xff08;一&#xff09;2.1 存儲數據的方案2.2 File&#xff1a;代表文本2.3 常用方法一&#xf…

挑戰用豆包教我學Java01天

今天是豆包教我學Java的第一天&#xff0c;廢話不多說直接開始。 1.每日題目&#xff1a; 基礎語法與數據類型 題目&#xff1a;編寫一個 Java 程序&#xff0c;從控制臺讀取兩個整數&#xff0c;然后計算它們的和、差、積、商&#xff0c;并輸出結果。題目&#xff1a;編寫…

文章記單詞 | 第67篇(六級)

一&#xff0c;單詞釋義 cylinder&#xff1a;英 [?s?l?nd?(r)] 美 [?s?l?nd?r] &#xff0c;名詞&#xff0c;意為 “圓筒&#xff1b;圓柱體&#xff1b;汽缸&#xff1b;&#xff08;有特定用途的&#xff09;圓筒形物品”。fool&#xff1a;英 [fu?l] 美 [fu?l]…

Make:獨立創造者手冊——從0到1的商業自由之路

目錄 如何獲得創業想法 ? 解決你自己的問題 ? 從微觀細分市場起步 ? 從問題出發&#xff0c;而非解決方案 ? 記錄與驗證想法 如何構建產品 ? 快速構建最小化產品 ? 對抗完美主義 ? 自行開發 vs. 外包 ? 學習基礎編程的必要性 案例與洞見 ? Levelsio的70個項目與5%成…

spark基本介紹

一、Spark概述 Spark是一種基于內存的快速、通用、可拓展的大數據分析計算引擎。 Hadoop是一個分布式系統結構的基礎架構。 二、Spark與Hadoop相比較的優勢&#xff1a; 1. 處理速度&#xff1a;Hadoop&#xff1a;數據處理速度相對較慢 Spark&#xff1a;速度比Hadoop快很…

Pdf轉Word案例(java)

Pdf轉Word案例&#xff08;java&#xff09; 需要導入aspose-pdf.jar 需要先手動下載jar包到本地&#xff0c;然后通過systemPath在pom文件中引入。 下載地址&#xff1a;https://releases.aspose.com/java/repo/com/aspose/aspose-pdf/25.4/ <dependency><groupId&…

探索 C++ 語言標準演進:從 C++23 到 C++26 的飛躍

引言 C 作為一門歷史悠久且廣泛應用的編程語言&#xff0c;其每一次標準的演進都備受開發者關注。從早期的 C98 到如今的 C23&#xff0c;再到令人期待的 C26&#xff0c;每一個版本都為開發者帶來了新的特性和改進&#xff0c;推動著軟件開發的不斷進步。本文將深入探討 C23 …

如何有效防御服務器DDoS攻擊

分布式拒絕服務&#xff08;DDoS&#xff09;攻擊通過大量惡意流量淹沒服務器資源&#xff0c;導致服務癱瘓。本文將提供一套結合代碼實現的主動防御方案&#xff0c;涵蓋流量監控、自動化攔截和基礎設施優化。 1. 實時流量監控與告警 目標&#xff1a;檢測異常流量并觸發告警…

【Bootstrap V4系列】學習入門教程之 組件-折疊(Collapse)

Bootstrap V4系列 學習入門教程之 組件-折疊&#xff08;Collapse&#xff09; 折疊&#xff08;Collapse&#xff09;How it works一、Example二、Horizontal 水平的三、Multiple targets 多個目標四、Accordion example 手風琴示例 折疊&#xff08;Collapse&#xff09; 通…

C24-數組

數組的引入:方便對同一類型的數據進行管理(一個班級里的45個同學、一個籃子里的12個蘋果)數組的定義: 數據類型 數組名[常量表達式(也就是元素的個數)];int a[10]; //這里定義了一個能存放10個元素的整形數組數組初始化 完全初始化 int arr[3]{5,6,8};部分初始化 int arr[10]{…

手持小風扇方案解說---【其利天下技術】

春去夏來&#xff0c;酷暑時節&#xff0c;小風扇成為外出必備的解暑工具&#xff0c;近年來&#xff0c;隨著無刷電機的成本急劇下降&#xff0c;小風扇也逐步從有刷變無刷化了。 數量最大的如一箱無刷馬達&#xff0c;其次三相低壓無刷電機也大量被一些中高端風扇大量采用。…

C++函數棧幀詳解

函數棧幀的創建和銷毀 在不同的編譯器下&#xff0c;函數調用過程中棧幀的創建是略有差異的&#xff0c;具體取決于編譯器的實現&#xff01; 且需要注意的是&#xff0c;越高級的編譯器越不容易觀察到函數棧幀的內部的實現&#xff1b; 關于函數棧幀的維護這里我們要重點介…

CPU-GPU-NPU-TPU 概念

1.CPU 中央處理器&#xff08;Central Processing Unit&#xff0c;簡稱CPU&#xff09;作為計算機系統的運算和控制核心&#xff0c;是信息處理、程序運行的最終執行單元。CPU自產生以來&#xff0c;在邏輯結構、運行效率以及功能外延上取得了巨大發展。 2.GPU GPU&#xff0…

Java學習手冊:ORM 框架性能優化

一、優化實體類設計 減少實體類屬性 &#xff1a;僅保留必要的字段&#xff0c;避免持久化過多數據。例如&#xff0c;對于一個用戶實體類&#xff0c;如果某些信息&#xff08;如詳細地址&#xff09;不是經常使用&#xff0c;可以將其拆分到單獨的實體類中。使用合適的數據類…

XMP-Toolkit-SDK 編譯與示例程序

一、前言 最近在調研圖片的元數據讀寫方案&#xff0c;需要了解 XMP 空間以及如何在 XMP 空間中讀寫元數據&#xff0c;本文做一個相關內容的記錄。 XMP-Toolkit-SDK 以及 XMP標準簡介 XMP-Toolkit-SDK 是 Adobe 提供的一套開源軟件開發工具包&#xff08;SDK&#xff09;&a…

計算機硬件(南橋):主板芯片組FCH和PCH的區別

在計算機主板設計中&#xff0c;FCH&#xff08;Fusion Controller Hub&#xff09;和PCH&#xff08;Platform Controller Hub&#xff09;分別是AMD和Intel對主板芯片組中“南橋”&#xff08;Southbridge&#xff09;部分的命名。盡管兩者功能相似&#xff0c;但受不同廠商架…

數據庫系統概論-基礎理論

數據庫系統概述&#xff1a; 1、記錄&#xff1a;計算機中表示和存儲數據的一種格式或方法。 2、數據庫&#xff08;DataBase, DB&#xff09;&#xff1a;數據庫是長期儲存在計算機內、有組織、可共享的大量數據集合。可為各種用戶共享。 3、數據庫管理系統&#xff08;Dat…

在 R 中,清除包含 NA(缺失值)的數據

在 R 中&#xff0c;清除包含 NA&#xff08;缺失值&#xff09;的數據可以通過多種方式實現&#xff0c;具體取決于你希望如何處理這些缺失值。以下是幾種常見的方法&#xff0c;包括刪除包含 NA 的行、刪除包含 NA 的列&#xff0c;或者用特定值填充 NA。 1. 刪除包含 NA 的…