setTimeout()函數執行完結果卻是 五個6 的原因是?
for (var i = 1; i <= 5; i++) {
setTimeout(function timer() {
console.log(i);
}, i * 1000);
}
// 其实我们想得到的结果是1,2,3,4,5,结果却是五个6
雖然用js 閉包解決了問題,得到想要的1,2,3,4,5,但還是不明白上述的程式碼為什麼會出現五個6?
for (var i = 1; i <= 5; i++) {
(function(j) {
setTimeout(function timer() {
console.log(j);
}, j * 1000);
})(i);
//通过一个立即执行函数,为每次循环创建一个单独的作用域
首先需要明白的一點JS的任務機制是隊列機制。
所以沒走一次for循壞只是把setTimeout這個任務放到隊列後面,也就是setTimeout裡面執行的程式碼只會在執行完for循壞才會執行,所以那個時候i的值就是不滿足for循壞的值,才會去執行setTimeout的程式碼。
個人看法,有什麼說的不對的歡迎指出
var 改為 let 即可
var 是全域定義,i 沒有構成閉包,log(i)都是列印i的最終值 6
let 是區塊級定義域
setTimeout有2個特性,它的this與上下文的this分離,它的呼叫是非同步的。
這裡就是【非同步】造成的,for循環會先全部完成,再執行setTimeout,因為for循環每次執行到最後都是6了- -所以自然setTimeout再調用i就是五個6
解決方法一:
解決方法二:
解決方法三: