JS解决setTimeout循环值问题的几种方法

830 阅读2分钟

setTimeout对for循环的影响

let i;
for(i=0; i<6; i++){
  setTimeout(()=>{
    console.log(i);
  },0);
}

执行如上JS代码将会打印6个6,原因为在for循环体中setTimeout函数体中的代码必须在for循环语句结束时执行,此时变量i通过6次循环已经从0变为6,因此打印出6个6。

在for循环初始化i时使用局部变量

在for循环初始化i时,使用let i = 0; 将i变为循环体中的局部变量,利用此技巧可以在每次循环时生成一个i,从而使得循环体中setTimeout函数所使用的变量为当前循环次数下的i。代码如下:

for(let i=0; i<6; i++){
  setTimeout(()=>{
    console.log(i);
  },0);
}

执行以上代码即可打印0, 1, 2, 3, 4, 5。

将setTimeout变为立即执行函数

针对setTimeout在for循环中的问题,可以将setTimeout变为立即执行函数,使用闭包特性实现for和let搭配使用的效果,代码如下:

let i;
for(i=0; i<6; i++){
  !function(i) {
      setTimeout(()=>{
        console.log(i);
      }, 0)
    }(i);
}

在setTimeout函数上使用bind绑定行参

针对以上问题,在setTimeout函数上使用bind绑定行参也可以实现for和let搭配使用的效果,代码如下:

let i;
for(i=0; i<6; i++){
    setTimeout(function(i){
        console.log(i);
    }.bind(undefined, i),0);
}

在setTimeout函数上添加参数i

针对以上问题,在setTimeout函数上增加参数i也可以实现for和let搭配使用的效果,代码如下:

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