前言
若沒有搞清楚執行環境與執行堆疊的觀念在後續開發上其實會很混亂
執行環境
在 JavaScript 每一個函式都有「屬於自己的執行環境」,每執行一次便會產生一個新的執行環境。
舉例來講我們無法直接繞過函式去呼叫其他函式
function sayHi() {
function sayName() {
console.log('Bob');
}
}
sayName(); // sayName is not defined;
所以 sayName 就會被限制在 sayHi 中,當然變數也是相同的,就算你已經執行了它也是一樣
function sayHi() {
var name = 'Bob';
}
sayHi();
console.log(name); // name is not defined;
也因為每一個函式都有屬於自己的作用域以及屬於自己的 this,因此你每一次執行的函式都是不同的執行環境。
其中這個觀念也可以套用在 Node.js 以及瀏覽器中,瀏覽器與 Node.js 在執行時也會建立一個「全域執行環境」,也就是 window 及 global
執行堆疊
執行環境的生成與堆疊 (Execution Stack) 與函式的宣告順序無關,而是與呼叫的順序相關聯
以下面這段程式碼為例說明執行堆疊:
function sayHi(name){
//…
}
function doSomething(){
sayHi();
}
doSomething();
JavaScript 在運行上面這一段程式碼時其實是一層一層堆疊上去,而且是在特定的執行環境下運作
- 首先在瀏覽器開啟或是Node.js啟動時,全域執行環境就會被建立
- 接著我們執行doSomething函式,所以doSomething的執行環境被生成,且堆疊在全域執行環境之上
- 在doSomething中我們又執行了sayHi,因此sayHi的執行環境被生成,且堆疊在doSomething執行環境之上
同樣的,執行環境離開時,也是一層一層的離開。
- sayHi執行完畢時,sayHi執行環境會先離開
- 接著在doSomething執行完畢後,doSomething的執行環境也會離開
- 最後剩下全域執行環境