js的作用域是链式的,当for循环函数内部的子块有引用的时候是不会销毁的。这里运用了闭包,外层 function(i)保持着对i的引用,因此每次 i的值得以保留,每次调用定时函数内层function都有自己的私有变量值。

执行以下程序,下列选项中,输出结果正确的是()

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

A
①式输出结果为0 1

B
①式输出结果为1 1

C
②式输出结果为0 1

D
②式输出结果为1 1

正确答案:C

对于①式,虽然定时器的延迟执行时间为0秒,但是不影响定时器为异步任务,即定时器的执行在循环结束后,
当i = 2时,循环结束,此时再执行定时器的异步任务,输出结果为2 2;
对于②式,立即执行函数会形成独立的作用域,用来临时封装变量i,i从0到1,对应两个立即执行函数,同时,立即执行函数将i值传递给定时器。

立即执行函数IIFE 闭包 作用域链

A.setTimeout是异步的,定时函数被加入执行队列,等(for循环)主程序运行完毕时,此时再调用定时函数,i的值已经变为2,两次的定时函数都会共用i=2这个值,因此打印2个2

B. js的作用域是链式的,当for循环函数内部的子块有引用的时候是不会销毁的。这里运用了闭包,外层 function(i)保持着对i的引用,因此每次 i的值得以保留,每次调用定时函数内层function都有自己的私有变量值。 因此打印 0 1

②式中如果把function的参数i去掉,没有对i的引用,结果就和①式一样了

for(var i = 0;i<2;i++){
(function(){ //去掉参数i
setTimeout(function(){console.log(i);},0)
}())
}
// 2 2


__EOF__

本文作者龙陌
本文链接https://www.cnblogs.com/longmo666/p/17836064.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   龙陌  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示