1.只有for循环时
for (var i = 0; i < 5; i++) {
console.log(i);
}
运行结果为0,1,2,3,4 ,这是大家都知道的
2.在for循环中添加setTimeout
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
},i*1000);
}
运行结果为每隔一秒输出一个5, 最后输出5,5,5,5,5
原因:在i = 0时,由于js是异步运行机制,导致当setTimeout计时的过程中,for循环继续在执行,又因为for循环的执行时间远远小于计时时间,所以for的循环完成即i = 5.当i = 0时,开启一个定时, i = 1时又开启一个定时,i=2时开启一个定时,所以开启了5个定时,当第一个定时时间到了之后for循环执行了5次,开启了5个定时,所以i = 5,后面的定时器就会按照开启的间隔时间依次输出5
如下
结果为
3.添加闭包
for (var i = 0; i < 5; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
},i*1000);
})(i);
}
执行结果0,1,2,3,4
原因
由于定时函数在闭包内,每次都将i的值传入了闭包内,不会由于for循环的继续执行而被污染,外部的for循环的i值不会影响闭包内部的值
4.闭包内不传递参数
for (var i = 0; i < 5; i++) {
(function () {
setTimeout(function () {
console.log(i);
},i*1000);
})(i);
}
执行结果:5 5 5 5 5
原因
由于没有往闭包内传递参数,所以i的值一直为for循环中的i的值,所以结果为5个5
5.setTimeout中添加立即执行函数
for (var i = 0; i < 5; i++) {
setTimeout((function () {
console.log(i);
})(),i*1000);
console.log(i,"执行第" + i + "次for循环");
}
执行结果0,1,2,3,4
原因
由于是立即执行,则不会等待setTimeout的定时,会马上执行,然后再执行下面的代码