###### tags: `JavaScript - 執行環境、作用域` # 執行環境(Execution Context)與執行堆疊(Execution Stack) ### 1. 執行環境 : 當JavaScript在執行時會產生執行環境,最外層會產生全域執行環境 (全域變數 : window、this) ,接下來才是被呼叫的函式 (還沒被呼叫執行時是不會產生執行環境,也不會產生內部變數) 。 因此,執行環境就分為全域執行環境和函式 (局部) 執行環境兩種,每個執行環境都有一個屬於自己的環境對象 (變數) 。 函式重複的呼叫式也會不斷重新產生新的執行環境。 ![](https://i.imgur.com/nZqvb9d.png) 當我們撰寫函式的時候就已經確定作用域,但是還沒被呼叫執行所以還沒產生執行環境,函式內的變數也就無法取得。 ```javascript= // 全域作用域 function funcA() { // 函式作用域 var a = 'a'; ... }; function funcB() { // 函式作用域 var b = 'b'; ... }; ``` ```javascript= function sayHi() { function sayName() { console.log('Kelvin'); } } //因函式sayHi()執行環境沒有產生,內部sayName()也沒產生出來 sayName(); // sayName is not defined; ``` ### 2. 環境堆疊 (Call Stack) : 讓我們直接看一個範例 : ```javascript= function a() { var a = 'a'; console.log('a'); b(); }; function b() { var b = 'b'; console.log('b'); c(); }; function c() { var c = 'c'; console.log('c'); }; // 呼叫 a()函式 a(); // 1. 會依序產生執行環境 global > a > b > c // 2. 每個函式作用域的變數也會依序產生 ``` 上面範例因為每個函式內部都會再次呼叫其它函式,所以會形成堆疊 global > a > b > c 每個函式執行完成後,作用域也會跟著消失,堆疊離開順序為 c > b > a > global ![](https://i.imgur.com/rTsmWX3.png)