javascript - js 入坑題目:setTimeout()函數執行完結果卻是五個6的原因是?
黄舟
黄舟 2017-05-19 10:47:29
0
3
802

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);
        
//通过一个立即执行函数,为每次循环创建一个单独的作用域
黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

全部回覆(3)
PHPzhong

首先需要明白的一點JS的任務機制是隊列機制。

所以沒走一次for循壞只是把setTimeout這個任務放到隊列後面,也就是setTimeout裡面執行的程式碼只會在執行完for循壞才會執行,所以那個時候i的值就是不滿足for循壞的值,才會去執行setTimeout的程式碼。

個人看法,有什麼說的不對的歡迎指出

Peter_Zhu

var 改為 let 即可

var 是全域定義,i 沒有構成閉包,log(i)都是列印i的最終值 6

let 是區塊級定義域

for (let i = 1; i <= 5; i++) {
        setTimeout(function timer() {
            console.log(i);
        }, i * 1000);
    }
为情所困

setTimeout有2個特性,它的this與上下文的this分離,它的呼叫是非同步的。

這裡就是【非同步】造成的,for循環會先全部完成,再執行setTimeout,因為for循環每次執行到最後都是6了- -所以自然setTimeout再調用i就是五個6

解決方法一:

var 换 let

解決方法二:

楼主自己用的闭包

解決方法三:

//类似于方法二,使用setTimeout的第三个参数直接传参
  for (var i = 1; i <= 5; i++) {
    setTimeout(function(i) {
      console.log(i);
    }, i * 1000,i);
  }
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板