为什么以下代码会打印出6个6,而不是012345呢?
let i = 0
for(i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
原因:
setTimeout
是用于延迟执行代码的函数,它会把要执行的函数放到 Event Loop 的最后面去,而当前循环体又在setTimeout
前面,因此上面的代码相当于:
let i = 0;
i++;
i++;
i++;
i++;
i++;
i++;
console.log(i)
console.log(i)
console.log(i)
console.log(i)
console.log(i)
console.log(i)
因此会打印出6个6。
而使用 let
配合 for
循环就可以避免这个问题了:
for(let i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
// 0,1,2,3,4,5
使用闭包和立即执行函数也可以实现:
for(var i = 0; i < 6; i++) {
setTimeout(
(function(){
var n = i;
return function() {console.log(n)}
})()
)
}
给setTimeout
传入一个立即执行函数,立即执行函数会马上求值而不是等到Event Loop的最后,利用这个机会,把当前循环内的i
记录在函数体内,和return的函数形成闭包,也就能打印出i
传入时的值了。
网友评论