閉包基本上是內部函數可以訪問其范圍之外的變量,可用于實現隱私和創建函數工廠
定義一個數組,循環遍歷這個數組并在延遲3秒后打印每個元素的索引
先看一個不正確的寫法:
const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {setTimeout(function() {alert('The index of this number is: ' + i);console.log('The index of this number is: ' + i);}, 3000);
}
看下執行效果:
如上圖:3秒后每次都是打印4,而不是0,1,2,3。
原因:因為setTimeout
函數創建的是一個可以訪問其外部作用域的函數(閉包),該作用域包含索引i
的循環。經過3
秒后,i
的值已經變為4
。
正確的寫法:寫法一:
const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {setTimeout(function(i_local){return function () {alert('The index of this number is: ' + i_local);console.log('The index of this number is: ' + i_local);}}(i), 3000)
}
寫法二:
const arr = [10, 12, 15, 21];
for (let i = 0; i < arr.length; i++) {setTimeout(function() {alert('The index of this number is: ' + i);console.log('The index of this number is: ' + i);}, 3000);
}