js_let与var在for循环中的底层实现模拟
for循环的执行顺序
-
for循环的代码如下
-
var a = [] for (var i = 0; i < 3; i++) { a[i] = function () { console.log(i) } } a[0]() // 3 a[1]() // 3 a[2]() // 3 -
其调用顺序为:
- 定义循环变量
var i = 0 - 判断循环
i<3 - 判断结果为true则执行循环体代码
- 循环变量自增
i++
- 定义循环变量
-
当使用var声明变量时的for循环的底层实现
-
上面的代码相当于
-
var a = [] var i = 0 if (i < 3) { a[i] = function () { console.log(i) } } i++ // 1 if (i < 3) { a[i] = function () { console.log(i) } } i++ // 2 if (i < 3) { a[i] = function () { console.log(i) } } i++ // 3 // false 不执行退出循环 if (i < 3) {} a[0]() // 3 a[1]() // 3 a[2]() // 3
-
当使用let声明变量时的for循环底层实现

- let声明变量时的for循环代码
var a = []
for (let i = 0; i < 3; i++) {
a[i] = function () {
console.log(i)
}
}
a[0]() // 0
a[1]() // 1
a[2]() // 2
- 使用let声明变量时的底层实现模拟
var a = []
let i = 0
if (i < 3) {
// 模拟底层实现
let k = i // js引擎通过赋值操作
a[k] = function () {
console.log(k)
}
}
i++
if (i < 3) {
let k = i
a[k] = function () {
console.log(k)
}
}
i++
if (i < 3) {
let k = i
a[k] = function () {
console.log(k)
}
}
i++
// 判断为false 跳出循环
if (i < 3) {}
a[0]() // 0
a[1]() // 1
a[2]() // 2
- 使用引用值作为let声明变量的赋值
var a = []
for (let i = {
num: 0
}; i.num < 3; i.num++) {
a[i.num] = function () {
console.log(i.num)
}
}
a[0]() // 3
a[1]() // 3
a[2]() // 3
- 使用引用值作为let声明变量的赋值的底层实现模拟
var a = []
let i = {
num: 0
}
if (i.num < 3) {
// 块作用域中只会复制父作用域中let所声明的循环变量
let k = i
a[k.num] = function () {
console.log(k.num)
}
}
i.num++
if (i.num < 3) {
let k = i
a[k.num] = function () {
console.log(k.num)
}
}
i.num++
if (i.num < 3) {
let k = i
a[k.num] = function () {
console.log(k.num)
}
}
i.num++
// 判断为false, 跳出循环
a[0]() // 3
a[1]() // 3
a[2]() // 3
参考博客
[for循环中let与var的区别,块级作用域如何产生与迭代中变量i如何记忆上一步的猜想]https://www.cnblogs.com/echolun/p/10584703.html

浙公网安备 33010602011771号