📅  最后修改于: 2023-12-03 15:35:54.135000             🧑  作者: Mango
我们有如下的代码片段:
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000);
}
我们期待的输出是每隔一秒打印一个数字,从0到4。但实际上,该程序会每隔一秒打印5个数字5,而不是从0到4。这是为什么呢?
原因是因为 setTimeout 的回调函数是异步执行的,当 for 循环执行完成后,i 的值已经变为了5。因此当回调函数被执行时,它会打印出5个数字5。
要修复该程序,我们需要使用闭包来捕获当前的i值,以便在回调函数中使用。具体做法是在 setTimeout 函数中定义一个立即执行的匿名函数,在该匿名函数内返回一个新的匿名函数,该新函数会使用闭包捕获当前的i值并将其返回,这样回调函数就可以使用该值了。
for (var i = 0; i < 5; i++) {
(function(j) {
setTimeout(function() {
console.log(j);
}, j * 1000);
})(i);
}
在上面的代码中,我们定义了一个立即执行的匿名函数,该函数将当前的i值作为参数传递给一个新的匿名函数,该新函数使用闭包捕获了该i值,并在回调函数中使用它。这样我们就可以得到我们期待的输出了,即每隔一秒打印一个数字,从0到4。
使用闭包来修复匿名函数的行为是一个常见的技巧,它能够解决很多类似的问题。在编写 JavaScript 的时候,我们应该时刻记住异步执行和闭包的特点,以便更好地应对这些问题。