js闭包和定时器解读

原创 何遇 随笔 js 244阅读 2018-01-24 13:37:37 举报

题如下:javascript 代码

结果打印:0,1,2,3,4,5,5,5,5,5
好奇的是为什么不是5s后一次打印或则每5s打印一次
查了一些资料看得比较明白的是下面的理解:
setTimeout是一次执行函数,这里是i1s后执行,仅仅执行一次;for(var i=0;i<5;i++),i的每次取值都是执行setTimeout这个函数,并没有执行setTimeout里面的function(即闭包函数),
setTimeout里面的function是有setTimeout的定时触动的,也就是i
1s后执行,也就是说i从0~5时,一共执行了5次的setTimeout()函数,此时的i的值是5,
由于for语句的执行速度远小于1s,所以,1s后,由setTimeout()函数定时触动的闭包函数function()开始执行,alert(i);i的值已经是5了,所以相继打印5次5
外加老姚的回答:
setTimeout(fn, time),首先这是个函数setTimeout执行,他是同步执行的。表示的意思是告诉浏览器,time时间后,要执行fn,只是“告诉”而已。
time时间后,浏览器把fn插入事件队列中,如果插入时,事件队列时空的,那么fn就立即执行了。因为fn在setTimeout执行完毕之后才执行的,因此是异步的,即异步回调。
而setTimeout(fn, 1000 i)可以写成
var j = 1000
i;
setTimeout(fn, j)
因此是同步执行的。
fn中的i,是闭包中的i,始终拿到i最新的保存值的,而轮到fn执行时,i已经累加成了5了。
下文是老姚的讲解,大家不太懂的可以去看看:说一道面试题,不要栽跟头

评论 ( 4 )
最新评论
何遇 2F 2018-01-29 15:45:30 4F

谢谢老姚

何遇 1F 2018-01-29 15:44:02 3F

setTimeout((function () {
console.log(i)
})(), i*1000);在定时器里写个自执行函数就可以了

老姚 2018-01-25 09:59:37 2F

关于js单线程,最近有人写了一篇比较全的文章。
https://juejin.im/post/5a6547d0f265da3e283a1df7

singercoder 2018-01-25 09:11:14 1F

怎么修改让定时器输出按时间顺序1.2.3.4.5,而不是5个5