js 闭包逻辑面试题

for(var i =0;i<5;i++){

(function(){
setTimeout(function(){
console.log(i)
},i*1000)
})(i)
}
这个为什么在浏览器先输出一个5,然后每过1秒在输出四个5?

主要问题在于,自执行函数没有形参i,如果加一个形参i,输出的就是0-4了。如这样

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

这就是作用域的问题,for循环每执行一遍,都会生成一个异步函数setTimeout,由于这个时候是同步的,自执行函数里边的i,读取的就是每次for循环的i,所以每次执行相差1秒。然后js是单线程的,setTimeout需要等for执行完之后执行。这时候,for循环执行完使得i的值变为5,而自执行函数没有形参,setTimeout回调函数读的变量是自执行函数外的变量i,所以输出为5。也就是每隔一秒输出一个5。

你可以试着把5变成更大的数,也是一样的,输出的就是这个数。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2019-03-07
你在循环里面通过立即执行函数新建了5个定时任务,分别是等待0s,1s,2s,3s,4s
循环结束之后,定时任务在相应的时间节点触发,开始打印i变量值,而i经过循环之后值变成了5
第2个回答  2019-03-07
因为程序运行的速度在1秒之内,所以输出的时候循环已经执行完成
相似回答