参考文章:这个前端面试在搞事!
题目
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
}
答案
每隔一秒输出5
分析
由于setTimeout会延迟执行,所以处理结果是执行循环之后再将里面的函数压入事件队列。执行循环的时候压入队列的函数是:0s console.log(i);1s console.log(I);….所以每隔一秒输出i。而由于i是var类型的,由于变量提升,最后的i都变成5了。于是最后都打印5
如果将上面的代码变成这样:
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
}
显然是每隔一秒输出0,1,2,3,4了,因为let存在块级作用域。
那么将代码变成这样呢?
for (var i = 0; i < 5; i++) {
setTimeout((function(i) {
console.log(i);
})(i), i * 1000);
}
由于setTimeout里面是立即执行函数,于是便不会根据时间延迟将函数压入队列,而是直接进入事件循环执行。所以会直接进行输出0,1,2,3,4。