为了账号安全,请及时绑定邮箱和手机立即绑定

for循环中setTimeout的问题

for循环中setTimeout的问题

跃然一笑 2018-08-13 11:10:06
在群里看到的,这方面的知识有点欠缺,希望懂的人可以解答下啊(⊙o⊙)…for(var i=0;i<10;i++){   setTimeout((function(i){    return function(){        console.log(i);    }   })(i),1000);}for(var i=0;i<10;i++){   setTimeout((function(i){    return function(){        console.log(i);    }   })(i),(function(i){     return i*1000   })(i));}
查看完整描述

1 回答

?
浮云间

TA贡献1829条经验 获得超4个赞

首先,执行结果上面的仁兄已经说得很清楚了,第一种方式会在1000ms后很快打印出0至9,第二种方法会在代码执行后每相隔1000ms打印0至9的一个数字。
我们来分析代码:
首先,看这个函数:

(function(i){
   return function(){
       console.log(i);
   }
  })(i)

这样写的作用就是保证每次for循环中执行的setTimeout函数中的i的值都为当前循环时i的值,如果我们这样写:

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

同样也可以正常输出,只是会在1000ms后输出10个10,因为实际上在setTimeout中的函数执行的时候,for循环已经完成了,i的值已经变成了10,当然,我们也可以用es6中的“let”来定义一个块级作用域,就像这样:

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

上面的函数在支持es6语法浏览器中同样会有0到9的输出。

当你理解了(function(i){...})(i)只是为了在function(i)执行的时候i的值能够是当前for循环的i值这个点的时候,第二种方式与第一种方式的区别无非就是根据当前for循环的i值给setTimeout函数添加一个不同的延时罢了,自然也就能理解为什么第二种方式会每隔1000ms输出一个数字了。
建议题主去看一下闭包的相关知识,当然,有兴趣的话,也可以去了解一下“块级作用域”的含义。


查看完整回答
反对 回复 2018-09-22
  • 1 回答
  • 0 关注
  • 1445 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信