JavaScript 循环内的闭包——简单实用的例子
在 JavaScript 中,闭包指的是函数能够“记住”它所在的词法环境,即使在函数执行上下文(作用域)已经结束的情况下,依然可以访问到该作用域中的变量。闭包在循环中非常常见,特别是在处理异步操作时。
在 JavaScript 中,闭包在循环中使用时可能会导致一些意想不到的行为。例如,如果你希望在循环内部定义的函数使用当前的循环变量,那么你可能会遇到变量共享的问题。来看一个例子:
for (var i = 1; i <= 3; i++) { setTimeout(function() { console.log(i); }, 1000); }
输出:
4 4 4
在这个例子中,setTimeout 回调函数在 1 秒后执行,循环已经结束,此时 i 的值为 4,因此每个回调都会输出 4。
setTimeout
i
4
为了使每个回调函数输出当前的 i 值,我们可以使用闭包创建一个新的词法环境,使得每个 i 都有其独立的作用域:
for (var i = 1; i <= 3; i++) { (function(currentI) { setTimeout(function() { console.log(currentI); }, 1000); })(i); }
1 2 3
currentI
let
ES6 引入的 let 关键字,可以更自然地解决这个问题,因为 let 在块作用域(block scope)中声明变量:
for (let i = 1; i <= 3; i++) { setTimeout(function() { console.log(i); }, 1000); }