---
# System prepended metadata

title: Closure 閉包 簡述

---

# Closure 閉包 簡述

## 先備概念
### Outer Enviroment 與 Scope Chain 的概念簡述

<img src="https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7688a3a5-4faf-4d75-a247-ae5afaafca44/Screen_Shot_2021-05-07_at_12.21.12_AM.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20210903%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210903T141635Z&X-Amz-Expires=86400&X-Amz-Signature=643939943aeff0fdad861b99570a5ed8c66a2f397e724b29b42e3a7b9cba5dc9&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22Screen_Shot_2021-05-07_at_12.21.12_AM.png%22" width="800px">

<br >

:::success
在一個 execution context 的 Creation Phase（創建階段），JS Engine 會建立這個 Execution Context 的 Outer Environment 的資訊
:::

<br >

#### Outer Environment 是什麼，由一個 function 被宣告所在的位置（Lexical Environment）來決定
```javascript=
function b(){
	console.log(myVar);
}

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

const myVar = 1;
a();

//1
```

<img src="https://s3.us-west-2.amazonaws.com/secure.notion-static.com/9991e9cd-8114-4a94-a834-748cba6a879d/Screen_Shot_2021-05-12_at_7.15.20_PM.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20210903%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210903T141840Z&X-Amz-Expires=86400&X-Amz-Signature=7d33f2a03aa22fa0b8f4764ea9dcda607e8ee9a23b5ab36d61e3466b7ae50ac0&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22Screen_Shot_2021-05-12_at_7.15.20_PM.png%22" width=600px>

:::success
**Scope Chain** 就是當一個 Execution Context 內之內找不到需要的變數
JS Engine 一路往 **Outer Environment** 找的這個機制
:::

<br >

## Closure 閉包
> ### 與 Execution Context, Execution Stack, Scope Chain 概念有關
> ### JS Engine 運作時產生的現象/特性 feature

[過程解釋 PPT](https://docs.google.com/presentation/d/1CkxpyH7EtbI8BolwCrWba2Vd7dE3Itb64Lp692_a0ng/edit?usp=sharing)

```javascript=
function greet(whattosay){
    return function(name){
        console.log(`${whattosay} ${name}`);
    }
}

const sayHi = greet("Hi");
sayHi('Tony');
```


>![](https://i.imgur.com/HHyGXq8.gif)
> 即使 greet function 的 Excecution Context 已經從 execution stack 中 pop off 不再存在了，在 greet function 內宣告的 function 仍然可以 reference 到 greet function 裏的 memory space
> 
> 因此，sayHi function 沿著 scope chain ，可以拿到 greet function 被 invoke 時，greet function 曾經在 execution stack 中的變數的值。

**“execution context 會包裹住一個 function 所有它沿著 scope chain 應該要可以 access 的 outer variables”** 
這個 JS engine 運作的方式，這個現象，我們稱為 closure 閉包


#### 另一個 Closure 的範例

```javascript=
const complexMultiply = (x) => {
      return function(y){
          return function(z){
              return x * y * z;
          }
      } 
};

//console.log(complexMultiply(2)(3)(4)); //24
//console.log(complexMultiply(3)(4)(5)); //60 
```
