JavaScript 的兩個重要觀念:Execution Context, Lexical Environments - JS 學習筆記
若要深入學習 JavaScript,就需要認知到你寫的這段程式碼,是如何被翻譯給電腦執行的。以下三個名詞則是了解 JavaScript Engine 是如何運作的重要觀念:
- Lexical Environments - 詞彙環境
- Execution Context - 執行環境
如果你是剛接觸這門語言,甚至是剛接觸程式語言的人,或許會傻在這裡。我起初見到這幾個名詞的時候,也愣了很久,一愣就是兩三年,程式碼都寫了萬行了,還是沒有很了解其背後運作的原理。但,這幾個觀念對於想學好 JavaScript 的人來說,絕對是不得不弄懂的檻。
JavaScript Engine
這邊提的兩個觀念,都是以 JavaScript Engine 的角度出發。畢竟當我們寫完一段程式碼,要讓電腦能讀的懂並且執行,少不了的就是幫我們「翻譯」程式碼的 JavaScript Engine。
像是你常在用的瀏覽器,如 Chrome, Safari, Firefox 或是 Edge 等等,裡面都有 JavaScript 的直譯器,用來將下載下來的 JavaScript 腳本轉譯執行。像是 Google 的 V8 及 Mozilla 的 SpiderMonkey 就是比較知名的 JavaScript Engine。
Lexical Environments 詞彙環境
什麼是詞彙環境?
簡單來說就是:寫在哪,很重要。
先來看一段有一點小繞的程式碼,判斷一下輸出的結果為何:
1 | function b() { |
我們從倒數第二行宣告變數開始,來看整段程式碼執行的過程
- 宣告全域變數
myVar = 'global'
,並呼叫a()
- 函式 a 中宣告
myVar = 'a'
,並呼叫函式 b - 函式 b 中印出 myVar
現在來看看,總共有兩個地方宣告了 myVar 這個變數,一是全域變數、二是函式 a 中。
那麼問題是,函式 b 會印出全域的 myVar(印出 global
)還是函式 a 的 myVar(印出 a
)呢?
答案是印出:global
有出乎你的意料嗎?或許你會覺得函式 b 是在函式 a 裡被呼叫的,不是應該看函式 a 中宣告的 myVar 嗎?但 JavaScript Engine 會說,要抓哪裡的變數,要看你寫在哪,也就是看看詞彙環境:
如果這個函式的 scope 用了沒在此函式內宣告的變數,JavaScript Engine 就會往上一層找,而這個上一層是看你寫在哪,而不是看這個函式被誰呼叫。因此,函式 b 在程式碼中的位置,是在全域的下面一層,和函式 a 是平行的,理所當然函式 b 找不到 myVar 這個變數時,就會往全域(函式 b 的上一層)尋找,找到 global
。
Execution Context 執行環境
也有人將其翻譯成執行上下文。
(未完待續)