for循环中的setTimeout

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

这段代码的输出是连续出现五个5。那怎么才能让他连续打出0-4呢?

打印出五个5的原因

这是因为setTimeout的延迟加载,所谓延迟加载就是指setTimeout先将回调函数放到等待队列中等待区域内其他主程序执行完毕后,按时间顺序先进先出执行回调函数。本质上是作用域的问题。

所谓本质上是作用域问题,在我理解上就是目前根据for循环遍历出五个
setTimeout,每个setTimeout在运行的时候都会将function函数压入队列,但是由
于var声明的变量在全局环境都会被调用,所以在执行压入下一个function的时
候,会改变上一个已经压入队列的function中的变量i,所以最后会打印五个5.

知道了问题的原因,就可以进行修改了。

解决

使用let、闭包、setTimeout第三个参数、拆分结构https://www.cnblogs.com/wl0804/p/11987833.html

其中闭包的方式除了用到了js的闭包还用到了立即执行函数。
下面的解释来:https://www.jianshu.com/p/d9adadcb05f8
立即执行函数,顾名思义,声明一个函数,并立即执行它。
首先我们区分一下函数声明和函数表达式:区分函数声明和函数表达式最简单的方法是看function关键字出现在声明中的位置。如果function是声明中的第一个词,那么就是一个函数声明,否则就是一个函数表达式。
所以我们可以用一个()把函数扩起来,让他成为一个函数表达式。然后在用自调用的方式将数据传入function中:

for(var i=0;i<5;i++){
        (function(j){
            setTimeout(function(){
                console.log(j)
            },1000)
        })(i)
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容