範圍鏈 (Scope Chain)

延續上一章節的執行堆 (Execution Stack),進一步介紹執行堆中的範圍鏈 (Scope Chain),’範圍’代表我能取到變數的地方,而’鏈’則是外部環境參照的連結

在 JavaScript 中每個執行環境都有一個參照的外部環境,如果在函數執行時沒有找到該變數,JavaScript 就會往外向外部環境尋找,和這個函數的程式碼在哪裡被寫出來無關,只與執行環境被創造和你呼叫的時間點有關

1
2
3
4
5
6
7
8
9
10
11
12
13
function b() {
console.log(myVar);
}

function a() {
var myVar = 2
b();
}

var myVar = 1;
a();

// 1

如下圖所示,這整個執行堆就稱為範圍鏈 (Scope Chain),’範圍’代表我能取到變數的地方,而’鏈’則是外部環境參照的連結,外部環境不一定是正下方的環境,正下方的環境只代表程式碼的物理位置,稱之為 ‘詞彙環境’;換個說法,外部參照會找到被函數創造的執行環境

當我們將函數 b 換個環境如下

1
2
3
4
5
6
7
8
9
10
11
12
13
function a() {
function b() {
console.log(myVar);
}

var myVar = 2;

b();
}

var myVar = 1;
a(); // 2
b(); // b is not defined

b 會出現 not defined,原因是當程式碼執行時,a 在創造階段被創造後,並不會執行內部指令,而是會直接跳到該函數最後一行,所以 b 在全域環境中並不存在,直到 a 被呼叫後,才會在該執行環境創造 b 函數