for循环创建几个作用域
for (let i = 0; i< 3; i++) {
let a = i
setTimeout(() => {
debugger
let b = a
let c = i
}, 1);
}
断点 查看scope,运行结果
结论:可以看到for循环创建了两个作用域
- 一个是for循环本身创建的父级作用域,记录循环变量i的值
- 一个是for循环内部创建的子作用域,记录变量a的值
for循环的循环变量使用let声明到底是怎么做到变量隔离的
先引用一段阮一峰 ES6入门的内容
- 每一次循环都是一个新的块级作用域
- 每一次循环的i都是重新声明的
- javascript引擎会记住上一轮循环的值,初始化本轮的循环变量i
模拟代码
var a = [];
var _i; // 模拟js引擎,记录上一轮循环的值
{
let i = 0;
_i = 0;
if(i < 3){ // 创建for循环内部的子作用域
a[i] = function() {
console.log(i)
}
}
}
{ // 第二次循环,创建新的块级作用域
let i = ++_i;
if(i < 3){ // 创建for循环内部的子作用域
a[i] = function() {
console.log(i)
}
}
}
{
let i = ++_i;
if(i < 3){ // 创建for循环内部的子作用域
a[i] = function() {
console.log(i)
}
}
}
a[1](); // 1
再来模拟一次文章一开始的代码,看下作用域是否一致
var a = [];
var _i; // 模拟js引擎,记录上一轮循环的值
{
let i = 0;
_i = 0;
if (i < 3) { // 创建for循环内部的子作用域
let a = i
setTimeout(() => {
let b = a
let c = i
console.log(i)
}, 1);
}
} { // 第二次循环,创建新的块级作用域
let i = ++_i;
if (i < 3) { // 创建for循环内部的子作用域
let a = i
setTimeout(() => {
let b = a
let c = i
console.log(i)
}, 1);
}
} {
let i = ++_i;
if (i < 3) { // 创建for循环内部的子作用域
let a = i
setTimeout(() => {
debugger
let b = a
let c = i
console.log(i)
}, 1);
}
}
// 输出结果:0 1 2
运行结果:
结论:跟我们一开始的scope一致
- for循环创建了两个作用域,自身的循环变量的块级作用域,以及内部循环体的块级作用域
- 使用let声明的循环变量,每次循环都会创建新的块级作用域,以及声明新的循环变量
Happy Ending... 💃💃💃💃💃💃