for循环中执行setTimeout问题

代码片段:

for(var i=0;i<8;i++){
    setTimeout(function () {
         console.log(i)
     },0)
 }

//代码执行结果为:
输出了8次8,这跟js的执行顺序和作用域链有关。

1、js同步执行与异步执行
js的执行机制: js是单线程环境,从上到下、依次执行,即 同步执行;在这段代码中,for循环是同步代码,setTimeout是异步代码。
js在执行代码的过程中,碰到同步代码会依次执行,碰到异步代码就会将其放入任务队列中进行等待,当同步代码执行完毕后再开始执行异步代码,即 异步执行

2、js作用域问题
当同步代码执行完毕后,开始执行异步的setTimeout代码,执行setTimeout时需要从当前作用域内寻找一个变量 i ,此时for循环已执行完毕,当前 i=8,所以执行setTimeout时输出为8,任务队列中的剩余7个setTimeout也依次执行,输出为8。

3、常用解决方法
利用立即执行函数,当for循环执行时,就会立即执行setTimeout,从而使得到的每个副本i值都不一样,这样就可以得到想要的for循环的结果。如:

for(var i=0;i<8;i++){
    (function (x) {
        setTimeout(function () {
            console.log(x)
        },0)
    })(i);
}

//代码执行结果为:

posted on 2017-11-01 17:25  淡水无华  阅读(1064)  评论(3编辑  收藏  举报