簡介
理解JavaScript執行原理,我們需要理解以下兩方面內容。
- JavaScript引擎。
- JavaScript執行時環境。
JavaScript引擎
什麼是JavaScript引擎
JavaScript引擎是一個計算機程式,它的主要作用是JavaScript執行時將原始碼編譯為機器碼。
每個主流Web瀏覽器都有自己的JavaScript引擎,它通常由web瀏覽器供應商開發。
- Google Chrome V8。
- Mozilla Firefox Spider Monkey。
- Safari Javascript Core Webkit。
- Edge (Internet Explorer)
以前的JavaScript引擎主要在web瀏覽器使用,不過隨著nodejs的出現就打破了這種侷限。
V8引擎
V8包含了解析器(parser),直譯器(Ignition),優化編譯器(TurboFan )。
解析器(parser):用於生成抽象語法樹。
直譯器(Ignition):將原始碼轉換為位元組碼。
優化編譯器(TurboFan ):進行一些優化編譯優化處理,比如內聯快取。
下面是V8引擎的大體工作流程。
- 首先解析器先生成一個抽象語法樹。
- 然後直譯器根據語法樹生成V8格式的位元組碼。
- 優化編譯器再將位元組碼編譯成機器碼。
執行時環境
瀏覽器執行環境中,瀏覽器提供了Web API,如:HTTP請求,計時器,事件等。
伺服器執行環境中,nodejs提供了API。
下面是JavaScript在瀏覽器中執行時的架構,它包含一個記憶體堆、一個記憶體棧、一個事件迴圈、一個回撥佇列。
- 記憶體棧(
stack
),一個連續的記憶體區域,為每個執行的函式分配本地上下文。 - 記憶體堆(
heap
), 一個更大的記憶體區域,儲存動態分配的所有內容。 - 呼叫棧(
call stack
), 一種資料結構,記錄了我們在程式中的位置。 - 回撥佇列(
callback queue
),儲存非同步任務的回撥函式。 - 事件迴圈(
event loop
),持續檢查呼叫棧是否為空,如果為空,將回撥佇列中頭部回撥函式移動到呼叫棧執行。
執行時的呼叫棧
下面程式碼展示了JavaScript執行的呼叫棧變化。
function add(x, y) {
return x + y;
}
function print(x, y) {
console.log('x+y=',add(x, y))
}
print(1, 3)
非同步任務
JavaScript先執行了print
函式,然後呼叫Web API setTimeout()
,Web API儲存了setTimeout()
的回撥函式,3秒後將回撥函式新增到回撥佇列,事件迴圈發現呼叫棧為空,於是將佇列裡的回撥函式移至呼叫棧執行。
function add(x, y) {
return x + y;
}
function print(x, y) {
setTimeout(function (){
console.log('x+y=',add(x, y))
}, 3000)
}
print(1, 3)
小結
JavaScript執行主要依靠JavaScript引擎和執行環境,引擎將js原始碼翻譯成計算機所理解的機器碼,執行環境提供了一些與計算機底層通訊的API和執行實現。