题目描述:
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i); //依次输出3,3,3
}, 1000);
}
for (let j = 0; j < 3; j++) {
setTimeout(function () {
console.log(j); //依次输出0,1,2
}, 1000);
为什么用let会输出0、1、2?
- 经百度以及个人思考,
- 得出的结果是
- 函数在声明时会同时保存当时的作用域链,就是说当时的活动变量
在setTimeout中使用变量时会沿着作用域链去寻找该变量,
对于用上面let 声明的循环来说,由于块级作用域,每次循环相当于--{ let j = 0; function () { console.log(j); } } //第二次循环 { let j = 1; function () { console.log(j); } } //第三次循环 { let j = 2; function () { console.log(j); }
这些块级作用域相互独立,互不影响
综上,用let,输出的才是0、1、2
问题
对于所给两段for循环过程中,JavaScript围绕let变量、块级作用域、作用域链这几个关键词到底做了什么?
setTimeout
方法,该方法都会将调用的回调函数放入“任务队列中”,等待主线程(执行栈中)的事件全部执行完毕后,执行队列头的事件。setTimeout
方法放入的回调函数,其作用域链中记录的是i的初始值0
1
的变量i