一、作用域是什麼 (學習筆記)—— 《你不知道的JavaScript》
阿新 • • 發佈:2018-12-14
因為全部都是文字不太好理解,所以儘可能地把所有的文字都畫成了圖,便於理解。
作用域是什麼
傳統編譯流程:
JavaScript 引擎會在語法分析和程式碼生成階段,通過特定的步驟,對執行效能進行優化。包括冗餘元素優化等。
JavaScript 編譯,大部分情況下,發生在程式碼執行前的幾微妙(甚至更短)。
理解作用域
引擎、編譯器、作用域
var a = 1;
以上程式碼,經歷了兩個不同的宣告:
- 編譯器在編譯時的處理
- 引擎在執行時的處理
以 var a = 1; 為例,演示引擎、編譯器、作用域三者是如何工作的
變數的賦值操作會執行兩個動作:1. 編譯器在當前作用域中宣告一個變數; 2. 執行時引擎在作用域中查詢該變數,找到便賦值,找不到丟擲異常。
LHS && RHS
先來張圖,解釋什麼是 LHS、RHS
看下面程式碼,加深理解
console.log(a); // 對 a 的引用是 RHS 引用。因為沒有對 a 賦值,而是查詢並取得 a 的值。
a = 2; // 對 a 的引用是 LHS 引用。不用關心 a 的值是什麼,只需要為 = 2 這個賦值操作找到一個目標。
引擎和作用域的對話
以下面程式碼為例:
function foo(a) { console.log(a); } foo(2);
小測驗
把自己當做引擎,同作用域進行一次“對話”。
function foo(a) { varb = a; return a + b; } var c = foo(2);
1. 找到其中所有的LHS查詢。(這裡有3處!)
2. 找到其中所有的RHS查詢。(這裡有4處!)
作用域巢狀
當一個塊或函式巢狀在另一個塊或函式中時,就發生了作用域巢狀。因此,在當前作用域中無法找到該變數時,引擎會在當前巢狀的作用域的外層繼續查詢,直到找到該變數,或抵達最外層作用域(全域性作用域為止)。
看以下程式碼:
function foo(a) { return a + b; } var b = 1; foo(2);
對 b 進行的 RHS 引用無法在函式 foo 內部完成,但可以在上一級作用域(在這個例子中就 是全域性作用域)中完成。
我們來模擬一下以上程式碼的引擎與作用域的對話。
注:以上所有的文字、程式碼都是本人一個字一個字敲上去的,圖片也是一張一張畫出來的,轉載請註明出處,謝謝!