for (var i=1;i<=5;i++){ setTimeout(function timer(){ console.log(i); },i*1000); }
书上说:上面这段代码的预期是分别输出1-5,每一秒一次,每次一个。但实际上,代码在运行时会以每秒一次的频率输出五个6。
请问为什么会输出5个6,循环条件不是i<=5嘛
i*1000 ??? 直接用1000就代表每秒运行一次。
for (var i=1;i<=5;i++){
setTimeout(function timer()
{ console.log(i); },1000);
}
当执行timer方法时,for循环已经执行完毕了
var改为let变块作用域
var的话你没做闭包,计时器最后引用到的i都是i的循环后的值6,而不是即时值
for (var i=1;i<=5;i++){
setTimeout(
(function(i){
return function(){ console.log(i); }//这里的i才是引用即时遍历到的传入的i,形成闭包
})(i),
i*1000);
}
你在for循环中创建了5个定时器(注意定时器是异步执行的,这时只是创建了定时器并没有执行)。当i++为6时循环条件i<=5不成立就结束循环了。
在这之后定时器依次执行,这时for循环早就结束了,这个时候i已经是6了。
解决方法就是用闭包把每次循环i的值保存起来。