有點經驗的前端工程師,對於「閉包」這詞應該是不陌生,就算平常沒用到,很多公司也很愛面試這個詞,由於我自己平常也很少用到閉包的概念來儲存資料,所以想藉由記錄的方式來理解一下這個功能

首先先簡單理解一下變數在函式裡跟及`函式外時,瀏覽器的記憶體是如何運作的

1.變數demoData在函式getData()外時,記憶體被用了32MB

2.變數demoData在函式getData()內時,記憶體被用了2.5MB,因為在執行完getData()的函數後,因為沒辦法再參照到demoData這個變數,所以這個變數的記憶體就會被釋放掉

3.那有沒有辦法儲存函式裡的變數,答案是可以的,假設我們在getData()裡面再放入另一個子函式setTimeOut(), 然後把變數demoData移到裡面去setTimeOut()裡面去,然後來看看記憶體使用的情況,如下圖所示,記憶體空間此時跟變數放在函式外時是一樣的,被佔用了32MB

4.由於我們這邊的setTimeOut()設定為10秒鐘,10秒鐘後,記憶體的佔用空間此時又變成2.5MB

所以由上面4個小步驟我們可以發現我們可以在子函式裡去使用父函式所宣告的變數,可以避免父函式所宣告的變數在沒有任何參照的情況下,被記憶體直接釋放掉,這就是所謂的「閉包」概念

簡單講,就是把函式裡的變數,用子函式把它儲存起來

 

接下來我們用一個簡單的範例來呈現這概念

如下圖所示我們在函式立再建立一個可以被return的子函式,在該子函式裡將父函式宣告的變數money放到要被return的子函式裡,直接來看結果,最後return的money值會是1100

1. 首先先執行storeMoney()的函式,此時的money為1000

2. 由於在子函式中有放了一個money的變數,該變數的值是當執行其子函式時,此時money的值由於範圍鍊的概念,必須向外層(此例為父層)尋找,而父層的這個變數money必須保存起來,子層的變數money才能使用

2.1 在這邊要注意的是storeMoney()本身是一個表達示,表達示本身會回傳一個直,如下圖所示,在該   例中它回傳的是一整個函式

3. 由於上層money這變數被保存起來,給後面子函式用,因此當執行storeMoney()(100)時,回傳的結就就會是1000+100 = 1100

總結: 所謂的閉包,就是一個函式可操作另一個函式的作用範圍的變數,當一個函式在返回一個作用域時,變數可以被儲存在作用域裡,