###### tags: `JavaScript - 執行環境、作用域`
# 執行環境(Execution Context)與執行堆疊(Execution Stack)
### 1. 執行環境 :
當JavaScript在執行時會產生執行環境,最外層會產生全域執行環境 (全域變數 : window、this) ,接下來才是被呼叫的函式 (還沒被呼叫執行時是不會產生執行環境,也不會產生內部變數) 。
因此,執行環境就分為全域執行環境和函式 (局部) 執行環境兩種,每個執行環境都有一個屬於自己的環境對象 (變數) 。
函式重複的呼叫式也會不斷重新產生新的執行環境。

當我們撰寫函式的時候就已經確定作用域,但是還沒被呼叫執行所以還沒產生執行環境,函式內的變數也就無法取得。
```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
