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