javascript - js循环中的闭包
ringa_lee
ringa_lee 2017-04-11 12:06:58
[JavaScript讨论组]
for(var i=0; i< 3;i++){
  setTimeout(function() {
    console.log(i);
  }, 0);
}
输出结果是3,3,3  能否详细解释一下执行过程?
ringa_lee
ringa_lee

ringa_lee

全部回复(4)
黄舟

JS var不是块作用域,所以,只有一个变量叫做isetTimeout的回调函数是在for执行完之后执行的,即i的值不会再改变。于是,一个变量,不可能同时等于多个不同的值。或者说下面的代码和上面的是一样的:

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

JS 是单线程,意思是,一段代码在执行的时候不可能会被打断,不会突然跳转到其他地方的代码去运行。只有一段代码执行完毕,其他地方的代码才有可能执行。所以说for循环不会无缘无故的被打断,去其他地方执行代码。

console.log(i)只是函数声明的一部分,不属于for要执行的语句setTimeout(function(){console.log(i)},0),这句的意思是,定义一个函数其代码是“ console.log(i)”,设置一个定时器,0ms后执行这个函数。所以说在for循环里并不会执行console.log(i)这一句,因为它只是函数定义语句的一部分。

巴扎黑

所有的异步操作都是等同步操作执行完毕开始执行。
哪怕是setTimeout的间隔时间设置为0
for循环是同步的,每一次循环都会创造一个定时器并改变i的值。当循环执行完毕的时候i的值已经是3了,这个时候setTimeout才会开始执行,所以这时候输出的是3

PHP中文网

setTimeout 相当于一个异步处理,setTimeout的回调会在for循环结束后才触发,所以结果就都是3

伊谢尔伦

执行队列中已经放入了循环操作
而setTimeout是延迟执行,回调的执行会被放到执行队列的末端,就算延迟为0
所以就是,循环进行了三次,执行队列中在循环后面放入了三个函数执行

再来时上面的写法不包含块状作用域,i为上级作用域所有(上面代码如果没被其他闭包包裹的话即i属于window所有)
而循环结束之后三个函数的执行,函数内部没有i,所以往上级作用域寻找,找了i已经是经历了三次循环自增之后的了,所以console.log(i)输出3

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号