前言
到了我最喜歡的部分囉~我滿喜歡透過小範例來討論一些寫程式可能會遇到的一些問題,這非常實用,在這個小節內我們要使用一些不一樣的做法來解決這個問題哦。
題目君 1 號
1 | var arr = []; |
這是蠻容易遇到的問題,在此的輸出不會如我們所想會是 0 ,而是變成 5 ,而我們接下來要嘗試不同的方法把問題修正。
產生非預期的原因為何
- 因為並沒有使用函式包覆,因此再迴圈內宣告的
i
變數相當於全域變數 - 而執行迴圈時,並沒有執行函式,僅將函式放入陣列
- 而呼叫後的函式由於在所屬作用域找不到
i
,轉而向上層尋找i
解法 A
這邊提到第一種解法,可以多宣告一個函式並且使用閉包技巧來記住當前 i
的值。
1 | var arr = []; |
可以把它想像成這樣
解法 B
如果不想要額外宣告函式,也可以透過 IIFE 配合閉包的技巧來達成,關於 IIFE 的部分可以喚醒另外一個世界線的記憶(?
所以這段程式其實可以改寫成這樣,跟解法 A 差不多,只是把額外宣告函式的部分用 IIFE 取代掉了。
1 | var arr = []; |
解法 C
我個人比較喜歡的一種,因為最容易。那就是使用 ES6 新增的 let
來處理這個問題, let
的作用域是以 block 也就是大括號來劃分,而 let 在迴圈中的表現出的特性又有點不同,每次迴圈執行時都會產生一個不同的 i 。
1 | var arr = []; |
使用 let
來處理這樣的問題其實相當容易,就只是把 var
替換掉而已。
然而我們可以把每當迴圈執行時的這段過程想像成這樣
而實際把右邊的內容放到左邊執行,結果是一樣的。