执行以下程序,下列选项中,输出结果正确的是()
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))
}
立即执行函数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
setTimeout(function(){console.log(i)},0)先不执行;
setTimeout(function(){console.log(i)},0)
setTimeout(function(){console.log(0)},0)
setTimeout(function(){console.log(1)},0)所以输出0,1
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) ....① }