前端面试题
阅读这段代码:
for (var i;i<=5;i++){
setTimeout ( function timer (){
comsote .log(i)
},i*1000)
}
答:预期是分别输出数字1-5, 每秒1次,每次1个;但真实结果是每秒一次输出了5个6。
解析:
这就涉及到setTimeout的执行原理。setTimeout()是一个异步方法, 传递一个函数,
延迟一段时候把该函数添加到队列当中,并不是立即执行,而且必须等当前环境所有代码执行完以后, 才会运行。也就是说我们执行这个for循环的时候
setTimeout(fun(...), 1000)
setTimeout(fun(...), 2000)
setTimeout(fun(...), 3000)
setTimeout(fun(...), 4000)
setTimeout(fun(...), 5000)
五个函数先进入了队列, 然后等for循环结束后再依次出队 (粗略理解下, 实质上是回调函数)
for循环结束后, 此时i是等于6的, 所以每秒一次输出了5个6。
解决方法:
1.使用闭包
for (var i = 1; i <= 5; i++) {
(function(j) {
setTimeout(function timer() {
console.log(j);
}, j*1000)
})(i)
}
2.使用ES6的let
for (let i = 1; i <= 5; i++) {
setTimeout(function timer() {
console.log(i);
}, i*1000)
}