for (var i = 0; i <5; i++) {
// 每一次for循环的时候,setTimeout是立即执行的,但是里面的回调函数没有被执行,回调函数是异步的,会被放到了任务队列里面
setTimeout(function() {
console.log(i); // 执行此代码时,同步代码for循环已经执行完成
}, 0);
}
// 输出结果: 5 5 5 5 5
// 该问题有多种解决方案
// 方案一: 将var改为let
// i虽然在全局作用域声明,但是在for循环体块级作用域中使用的时候,变量会被固定,不受当前块级作用域以外的干扰。
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i); // i 是循环体内局部作用域,不受外界影响。
}, 0);
}
// 输出结果: 0 1 2 3 4
// 方案二: 利用闭包
for (var i = 0; i < 5; i++) {
(function (j) { // 此处传入的j是匿名函数传入的参数
setTimeout(function () {
console.log(j);
}, 0);
})(i) // 每次传入的参数是从for循环里面取到的值
}
// 输出结果: 0 1 2 3 4
// 方案三: 利用setTimeout第三个(及以上)参数
for (var i = 0; i < 5; i++) {
// 第三个以后的参数是作为回调函数的参数传进去
setTimeout(function (k) {
console.log(k);
}, 0, i); // 每次传入的参数是从for循环里面取到的值
}
// 输出结果: 0 1 2 3 4
前端菜鸟,如果有错误之处请指出