整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ
[JS奇怪的世界]No.39 閉包(二)
前言
在網路上搜尋相關閉包知識時,其實都會找到類似的範例程式,但是如果沒有釐清觀念,頓時會覺得很難。
閉包
所以在這一堂課算是驗證自己對於閉包的觀念是否已經清楚了,首先先準備一個函數 ↓
1 | |
接下來將執行 buildFunction() 存入變數 fs,所以這邊我們可以預期得到一個陣列 ↓
1 | |

所以我們可以這樣呼叫陣列裡面的函數,那預期應該會是什麼?
1 | |

可以看到答案是 3,絕對不是我下面沒有截圖。
為什麼當它到外部參數找 i 的時候會發現它們都一樣呢?回頭想一下執行堆。
首先在執行堆中 buildFunction() 會開始執行,然後跑三次,然後匿名函數會被建立,可是它們只是建立並沒有被執行,只是將函數放進去陣列中 (arr),接下來執行完畢就回傳 arr,所而 i 在執行完畢後最終停在 3,故而被保存在記憶體中,就像課程簡報一樣。

它們的環境是處於閉包,在匿名函數裡面它們找不到 i,所以會從範圍鏈去取得 i,而 i 目前為 3,這也是為什麼 i 會是 3 的原因。

但是如果我們希望是輸出 0…1…2 呢?那就這樣做。
1 | |

這樣就可以達到我們要的效果,而這邊主要使用的是 ES6 的 let,let 的特性就是只會存活在這個區塊,所以當這個區塊結束或離開後,就會被消滅,但在這邊 j 會被儲存在不同的記憶體位置中,所以每次 for 迴圈執行一次,就會產生一個新的記憶體位置的 j。
那另一種作法呢?
1 | |

這邊所活用的方式是先期講過的其中一種方式,因為要讓變數獨一無二那就要有一個唯一的執行環境,所以就是立刻執行環境 IIFE。
但是課程的寫法是這樣。
1 | |

基本上我覺得課程所講的方式較妥當,因為可以確保有執行環境。
圖源
整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ