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

詳解V8是如何執(zhí)行一段JavaScript代碼原理

 更新時間:2023年04月11日 10:05:52   作者:codinglin  
這篇文章主要為大家介紹了詳解V8是如何執(zhí)行一段JavaScript代碼原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

了解 V8 的執(zhí)行機制,能幫助你從底層了解 JavaScript,也能幫助你深入理解語言轉(zhuǎn)換器 Babel、語法檢查工具 ESLint、前端框架 Vue 和 React 的一些底層實現(xiàn)機制。因此,了解 V8 的編譯流程能讓你對語言以及相關(guān)工具有更加充分的認(rèn)識。

要深入理解 V8 的工作原理,你需要搞清楚一些概念和原理,比如編譯器(Compiler)、解釋器(Interpreter)、抽象語法樹(AST)、字節(jié)碼(Bytecode)、即時編譯器(JIT)等概念。

編譯器和解釋器

之所以存在編譯器和解釋器,是因為機器不能直接理解我們所寫的代碼,所以在執(zhí)行程序之前,需要將我們所寫的代碼“翻譯”成機器能讀懂的機器語言。按語言的執(zhí)行流程,可以把語言劃分為編譯型語言和解釋型語言。

編譯型語言在程序執(zhí)行之前,需要經(jīng)過編譯器的編譯過程,并且編譯之后會直接保留機器能讀懂的二進(jìn)制文件,這樣每次運行程序時,都可以直接運行該二進(jìn)制文件,而不需要再次重新編譯了。比如 C/C++、GO 等都是編譯型語言。

而由解釋型語言編寫的程序,在每次運行時都需要通過解釋器對程序進(jìn)行 動態(tài)解釋和執(zhí)行。比如 Python、JavaScript 等都屬于解釋型語言。

編譯器解釋器 是如何“翻譯”代碼的呢?具體流程你可以參考下圖:

1. 生成抽象語法樹(AST)和執(zhí)行上下文

編譯器或者解釋器后續(xù)的工作都需要依賴于 AST,而不是源代碼。

Babel 的工作原理就是先將 ES6 源碼轉(zhuǎn)換為 AST,然后再將 ES6 語法的 AST 轉(zhuǎn)換為 ES5 語法的 AST,最后利用 ES5 的 AST 生成 JavaScript 源代碼。

ESLint 是一個用來檢查 JavaScript 編寫規(guī)范的插件,其檢測流程也是需要將源碼轉(zhuǎn)換為 AST,然后再利用 AST 來檢查代碼規(guī)范化的問題。

通常,生成 AST 需要經(jīng)過兩個階段:

第一階段是分詞(tokenize),又稱為 詞法分析。其作用是將一行行的源碼拆解成一個個語法上不可能再分的、最小的單個字符或字符串。

第二階段是解析(parse),又稱為 語法分析。其作用是將上一步生成的數(shù)據(jù),根據(jù)語法規(guī)則轉(zhuǎn)為 AST。如果源碼符合語法規(guī)則,這一步就會順利完成。但如果源碼存在語法錯誤,這一步就會終止,并拋出一個“語法錯誤”。有了 AST 后,那接下來 V8 就會生成該段代碼的執(zhí)行上下文。

2. 生成字節(jié)碼

有了 AST 和執(zhí)行上下文后,那接下來的第二步,解釋器 Ignition 就登場了,它會根據(jù) AST 生成字節(jié)碼,并解釋執(zhí)行字節(jié)碼。

字節(jié)碼就是介于 AST 和機器碼之間的一種代碼。但是與特定類型的機器碼無關(guān),字節(jié)碼需要通過解釋器將其轉(zhuǎn)換為機器碼后才能執(zhí)行。使用字節(jié)碼可以減少系統(tǒng)的內(nèi)存使用。

3. 執(zhí)行代碼

生成字節(jié)碼之后,接下來就要進(jìn)入執(zhí)行階段了。解釋器 Ignition 除了負(fù)責(zé)生成字節(jié)碼之外,它還有另外一個作用,就是解釋執(zhí)行字節(jié)碼。

在 Ignition 執(zhí)行字節(jié)碼的過程中,如果發(fā)現(xiàn)有熱點代碼(HotSpot),比如一段代碼被重復(fù)執(zhí)行多次,這種就稱為 熱點代碼,那么后臺的編譯器 TurboFan 就會把該段熱點的字節(jié)碼編譯為 高效的機器碼,然后當(dāng)再次執(zhí)行這段被優(yōu)化的代碼時,只需要執(zhí)行編譯后的機器碼就可以了,這樣就大大提升了代碼的執(zhí)行效率。

其實字節(jié)碼配合解釋器和編譯器是最近一段時間很火的技術(shù),比如 Java 和 Python 的虛擬機也都是基于這種技術(shù)實現(xiàn)的,我們把這種技術(shù)稱為 即時編譯(JIT)。具體到 V8,就是指解釋器 Ignition 在解釋執(zhí)行字節(jié)碼的同時,收集代碼信息,當(dāng)它發(fā)現(xiàn)某一部分代碼變熱了之后,TurboFan 編譯器便閃亮登場,把熱點的字節(jié)碼轉(zhuǎn)換為機器碼,并把轉(zhuǎn)換后的機器碼保存起來,以備下次使用。

JavaScript 的性能優(yōu)化

對于優(yōu)化 JavaScript 執(zhí)行效率,應(yīng)該將優(yōu)化的中心聚焦在 單次腳本的執(zhí)行時間腳本的網(wǎng)絡(luò)下載 上,主要關(guān)注以下三點:

提升單次腳本的執(zhí)行速度,避免 JavaScript 的長任務(wù)霸占主線程,這樣可以使得頁面快速響應(yīng)交互。

避免大的內(nèi)聯(lián)腳本,因為在解析 HTML 的過程中,解析和編譯也會占用主線程。

減少 JavaScript 文件的容量,因為更小的文件會提升下載速度,并且占用更低的內(nèi)存。以上就是詳解V8是如何執(zhí)行一段JavaScript代碼原理的詳細(xì)內(nèi)容,更多關(guān)于V8 執(zhí)行JavaScript原理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論