首页 > 试题广场 >

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

[单选题]

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

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))
}
  • ①式输出结果为0 1

  • ①式输出结果为1 1

  • ②式输出结果为0 1

  • ②式输出结果为1 1

立即执行函数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
发表于 2021-12-12 11:46:05 回复(3)
第一段代码,i=0时,执行队列中放入:
setTimeout(function(){console.log(i)},0)
先不执行;
i=1时,执行队列中放入:
setTimeout(function(){console.log(i)},0)
for循环执行完了,再执行执行队列中的函数,此时i==2,所以两次都输出2

第二段代码,function(i){...}(i)传参了,保留了for循环执行时 i 的值,当i=0时,在执行队列中放入:
setTimeout(function(){console.log(0)},0)
i=1时,在执行队列中放入:
setTimeout(function(){console.log(1)},0)
所以输出0,1
编辑于 2022-04-07 17:16:52 回复(0)
如果将var换成let结果又会不一样
发表于 2022-03-10 10:19:31 回复(0)
for (var i = 0; i < 5; i++) { 
	setTimeout(function (){
		console.log(i);  
	 },1000);  
}
上面这段代码输出:5 5 5 5 5;因为 setTimeout 的 console.log(i); 的i是 var 定义的,所以是函数级的作用域,不属于 for 循环体,属于 global。等到 for 循环结束,i 已经等于 5 了,这个时候再执行 setTimeout 的五个回调函数(参考上面对事件机制的阐述),里面的 console.log(i); 的 i 去向上找作用域,只能找到 global下 的 i,即 5。所以输出都是 5。同理可以得到题目1段代码输出为2,2
for(var i = 0;i<2;i++){
setTimeout(function(){
    console.log(i)
    },0) ....①
}




发表于 2022-02-27 20:50:20 回复(0)
闭包,全局变量
发表于 2021-12-11 00:35:48 回复(0)
①式,把var 改成 let 输出就是0,1。为什么呢,setTimeout 还是异步的啊
发表于 2022-05-19 15:13:04 回复(2)
1
发表于 2022-03-10 23:21:21 回复(0)