---
# System prepended metadata

title: 執行環境(Execution Context)與執行堆疊(Execution Stack)
tags: [JavaScript - 執行環境、作用域]

---

###### 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)

