for循环中setTimeout的问题

在群里看到的,这方面的知识有点欠缺,希望懂的人可以解答下啊(⊙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));}


跃然一笑
浏览 1501回答 1
1回答

浮云间

首先,执行结果上面的仁兄已经说得很清楚了,第一种方式会在1000ms后很快打印出0至9,第二种方法会在代码执行后每相隔1000ms打印0至9的一个数字。我们来分析代码:首先,看这个函数:(function(i){ &nbsp;&nbsp;&nbsp;return&nbsp;function(){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log(i); &nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;})(i)这样写的作用就是保证每次for循环中执行的setTimeout函数中的i的值都为当前循环时i的值,如果我们这样写:for(var&nbsp;i=0;i<10;i++){ &nbsp;&nbsp;setTimeout((function(){&nbsp;&nbsp;&nbsp;return&nbsp;function(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log(i); &nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;})(),1000); }同样也可以正常输出,只是会在1000ms后输出10个10,因为实际上在setTimeout中的函数执行的时候,for循环已经完成了,i的值已经变成了10,当然,我们也可以用es6中的“let”来定义一个块级作用域,就像这样:for(let&nbsp;i=0;i<10;i++){ &nbsp;&nbsp;setTimeout((function(){&nbsp;&nbsp;&nbsp;return&nbsp;function(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log(i); &nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;})(),1000); }上面的函数在支持es6语法浏览器中同样会有0到9的输出。当你理解了(function(i){...})(i)只是为了在function(i)执行的时候i的值能够是当前for循环的i值这个点的时候,第二种方式与第一种方式的区别无非就是根据当前for循环的i值给setTimeout函数添加一个不同的延时罢了,自然也就能理解为什么第二种方式会每隔1000ms输出一个数字了。建议题主去看一下闭包的相关知识,当然,有兴趣的话,也可以去了解一下“块级作用域”的含义。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript