变量
代码如下:
function varLoop() {
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 0);
}
}
varLoop();
代码将会输出5个5。首先由于变量i通过var声明,为函数作用域,js解释器会对i进行变量提升至函数顶部,等效于
function varLoop() {
var i;
for (i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 0);
}
}
然后进入循环,每次执行循环体都会往任务队列里增加一个宏任务,即对同一个变量i(与下面的let区分开)进行打印,任务队列在同步代码(即循环)完成后才会开始执行,因此最终输出5个5。
而let声明的变量都是块级作用域,每一次循环体结束都会重新生成一个新的循环变量,因此在下面的代码中:
function letLoop() {
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 0);
}
}
每一个setTimeout中打印的,都是不同的变量,因此代码最终输出0,1,2,3,4。
用const声明的变量也有同样的特性,虽然不可以修改该变量的值,但是可以用于for-in循环遍历对象,以及for-of循环循环遍历数组中:
for (const i in {code: 200, msg: '成功'}) {
console.log(i); // 输出code, msg
}
for (const i of [1, 2, 'test']) {
console.log(i);
}
这就是因为每次循环都会创建一个新的循环变量i实例。
参考书:《Javascript高级程序设计》
本文探讨了JavaScript中使用var、let及const声明变量时,在循环与setTimeout宏任务结合时的不同表现,展示了作用域差异带来的结果变化,并举例说明了let与const声明变量的特点。
2302

被折叠的 条评论
为什么被折叠?



