js閉包,解決for迴圈變數未定義等類似問題
阿新 • • 發佈:2019-02-06
迴圈中的閉包 一個常見的錯誤出現在迴圈中使用閉包,假設我們需要在每次迴圈中呼叫迴圈序號
for(var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
上面的程式碼不會輸出數字 0 到 9,而是會輸出數字 10 十次。
當 console.log 被呼叫的時候,匿名函式保持對外部變數 i 的引用,此時 for迴圈已經結束, i 的值被修改成了 10.
為了得到想要的結果,需要在每次迴圈中建立變數 i 的拷貝。
避免引用錯誤
為了正確的獲得迴圈序號,最好使用 匿名包裹器(譯者注:其實就是我們通常說的自執行匿名函式)。
for(var i = 0; i < 10; i++) {
(function(e) {
setTimeout(function() {
console.log(e);
}, 1000);
})(i);
}
外部的匿名函式會立即執行,並把 i 作為它的引數,此時函式內 e 變數就擁有了 i 的一個拷貝。
當傳遞給 setTimeout 的匿名函式執行時,它就擁有了對 e 的引用,而這個值是不會被迴圈改變的。
有另一個方法完成同樣的工作;那就是從匿名包裝器中返回一個函式。這和上面的程式碼效果一樣。
for(var i = 0; i < 10; i++) { setTimeout((function(e) { return function() { console.log(e); } })(i), 1000) }