在上一次的筆記中([筆記] 談談JavaScript中closure的概念 -- Part 2),我們用進階的例子進一步的說明了closure的概念,那如果我們想要讓上一篇文章中的程式碼,輸出的結果是0, 1, 2的話,我們可以怎麼做呢?
原本的程式碼是這樣子,而且會輸出3, 3, 3的結果:
如果我們要讓他輸出的結果變成 0, 1, 2,我們可以這樣做。
方法一:使用LET
在最新的ES6(ECMAScript 6)中,我們可以使用關鍵字 let 來達到這樣的效果。透過let,可以讓每次跑的迴圈都建立到一個新的記憶體位置,因此最後指稱到的地方會是不一樣的,於是可以輸出0, 1, 2的結果。
方法二:在呼叫陣列的時候即執行函式
如果我們的瀏覽器還不支援ES6的話,我們可以讓這段程式在將function寫進陣列的時候,就加以執行這段function,也就是迴圈每跑一次,就執行一次function。記得我們要怎麼樣可以直接在function建立的時候就加以執行函式嗎?
沒錯,就是先前我們提到的IIFEs。
所以我們可以寫成這樣:
不得不說,這段程式碼看起來實在是有點複雜。讓我們來了解一下:
首先,當執行buildFunctions的時候,陣列裡面的匿名函式 function(j){...}這段因為是IIFEs,所以會直接被執行,並且把變數 i 帶入函式中,於是,當我們在執行 fs[0]( ) 的時候,因為在fs[0]( )的execution context中,已經存有變數 j ,所以當我們執行 fs[0]( ) 的時候,就可以得到0的結果。其他fs[1]( )和fs[2]( )的部分,也是以此類推。
程式範例
function buildFunctions(){ var arr = []; for(var i = 0; i < 3; i++){ arr.push( (function(j){ return function(){ console.log(j); }; }(i)) ) } return arr; } var fs = buildFunctions(); fs[0](); // 0 fs[1](); // 1 fs[2](); // 2→回到此系列文章目錄
0 意見:
張貼留言