let 与 闭包

for (var i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(i)
    }, i * 1000)
}

相信js新手们应该都写过类似的代码.在经过一番百度后,终于知道导致错误的原因是因为匿名函数中的变量引用的是同一个变量,所以结果显示相同.

解决这个问题的方法是使用闭包,创建一个新的作用域,代码会变成如下:

for (var i = 0; i < 5; i++) {
    (function (i) {
        setTimeout(function () {
            console.log(i)
        }, i * 1000)
    })(i)
}

因为每次循环都会创新的作用域,每个i都是引用的自己作用域的变量,所以结果正常.
ES6引入了let变量声明,for循环头部的let声明还有一个特殊的行为:

这个行为指出变量在循环过程中不止被声明一次,每次迭代都会被声明.随后的每个迭代都会使用上一个迭代结束时的值来初始化这个变量.
所以我们的代码变成如下:

for (let i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(i)
    }, i * 1000)
}

结果和预计一样.

你可能感兴趣的:(let 与 闭包)