理解块级作用域

128 阅读1分钟

学习到作用域的时候对这两段代码产生了一些疑惑

var a = []
for (let i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i)
    }
}
a[6]()  //6


var b = []
for (var j = 0; j < 10; j++) {
    b[j] = function () {
        console.log(j)
    }
}
b[6]()  //10

虽然知道let会产生块级作用域,可到底该怎么理解它在以上代码中的作用呢?

后来查阅了一些资料,终于能解释上面的代码了

首先大家都知道,由于变量j处于全局环境中,并且是用var声明的,所以j是一个全局变量。

执行循环时,循环体中的代码在不断地根据下标j给数组b[]赋值,值为函数function () { console.log(j) }

循环结束后,执行b[6],由于console.log(j)中的j指向的都是同一个全局变量j,所以数组的每个成员输出结果都是10。

而在第一段代码中,变量i是用let声明的,故i只在当前循环中有效。

所以在每执行一次循环之后,引擎并不会对原来的i进行操作,而是会重新创建一个i。在这里可能要问了,为什么这个i总能是“正确的值”,也就是新创建的i等于上一个i加上1。原因是,引擎会保存上一次i的值,并在此基础上计算新i的值。

我们也就知道了,不同次循环中,它们的console.log(i)中的i并不是同一个i,而是执行那次循环时i的值。