###### tags: `六角JS 直播班 - 2021 秋季班` JavaScript 閉包(closure) === 閉包(Closure)是函式以及該函式被宣告時所在的作用域環境(lexical environment)的組合。(取自MDN) 有點饒口,簡單來說,**閉包就是function內包著一個function,看到一個function內 return 了另一個 function,通常都是閉包的應用!** <br> ## 為什麼需要用到閉包? **先來看一個例子!** 如果今天需要寫一個計算水果攤上蘋果數量的函式,我們直覺上會這樣寫: ```javascript= let appleNum = 0; function appleCounter() { appleNum+=1; console.log(`有${appleNum}顆蘋果`); } appleCounter() //1 appleCounter() //2 ``` 看起來沒有問題,但如果今天除了要計算蘋果,還要計算橘子呢?那我們可能會這樣寫: ```javascript= //蘋果計算器 let appleNum = 0; function appleCounter() { appleNum+=1; console.log(`有${appleNum}顆蘋果`); } //橘子計算器 let orangeNum = 0; function orangeCounter() { orangeNum+=1; console.log(`有${orangeNum}顆橘子`); } appleCounter() //有1顆蘋果 appleCounter() //有2顆蘋果 orangeCounter()//有1顆橘子 orangeCounter()//有2顆橘子 appleCounter()//有3顆蘋果 ``` 看起來也沒問題,但如果今天水果攤上有100種水果呢? 這種寫法的話,不同的水果不能共用一個變數,會互相干擾,因此要為每種水果宣告一個獨一無二的變數,程式碼會變得冗長也會寫得很崩潰~ <br> ### 這時候就需要透過「閉包」來解決這個問題! **「內層的變數不會被釋放,可以被重複使用,但又不會被外層讀取,因此就不會出現互相干擾的問題!」** ```javascript= //蘋果計算器 function appleCounter() { let num = 0 function countApple() { num+=1 console.log(`有${num}顆蘋果`); } return countApple; } //橘子計算器 function orangeCounter() { let num = 0 function countOrange() { num+=1 console.log(`有${num}顆橘子`); } return countOrange; //把這個函式回傳出來,讓我們可以在外層使用它 } const appleResult = appleCounter() const orangeResult = orangeCounter() appleResult()//有1顆蘋果 appleResult()//有2顆蘋果 orangeResult()//有1顆橘子 orangeResult()//有2顆橘子 ``` 可以看到兩個函式中的變數num因為在不同的環境,所以不會互相干擾! **在外層宣告變數appleResult並呼叫appleCounter(),事實上會執行的是appleCounter()中的countApple()這一個function!** 這個寫法我覺得有點美中不足,好像還是很冗長,它甚至可以再更精簡一點: ```javascript= function fruitCounter(name) { let num = 0 //將countApple跟countOrange改成匿名函式 return function () { num++ console.log(`有${num}顆${name}`); } } const appleResult = fruitCounter("蘋果") const orangeResult = fruitCounter("橘子") appleResult() //有1顆蘋果 appleResult() //有2顆蘋果 orangeResult() //有1顆橘子 orangeResult() //有2顆橘子 ``` 我們只需要寫一個水果計算函示,帶入不同的參數即可計算每一種水果,不必再為了每種水果去寫一個專屬的函示,是不是簡潔又省事多了~~~ <br> 閉包是個很重要又有點不好懂的概念,如果有看到更多範例會再整理上來,感謝看到這邊😻 <br> >**參考資料:** [為什麼我們需要閉包(Closure)?它是冷知識還是真有用途? ](https://nissentech.org/why-do-we-need-closure/)[[JS] 深入淺出 JavaScript 閉包(closure)](https://pjchender.dev/javascript/js-closure/)