我的一个朋友和我正在讨论什么是JS中的闭包,什么不是。我们只是想确保我们理解正确。
让我们举个例子。我们有一个计数循环,并希望在控制台上延迟打印计数器变量。因此,我们使用setTimeout
和闭包来捕获计数器变量的值,以确保它不会打印N乘以N的值。
没有闭包或接近闭包的错误解决方案是:
for(var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
当然,它会在循环结束后打印10倍于i
的值,即10。
所以他的尝试是:
for(var i = 0; i < 10; i++) {
(function(){
var i2 = i;
setTimeout(function(){
console.log(i2);
}, 1000)
})();
}
按预期打印0到9。
我告诉他,他没有使用关闭来捕获i
,但他坚持说他是。我通过将for循环体放在另一个setTimeout
中(将他的匿名函数传递给setTimeout
)来证明他没有使用闭包,再次打印10乘以10。如果我将他的函数存储在var
中,并执行后循环,同样打印10乘以10。所以我的论点是他没有真正的捕获的值i
,使他的版本不成为一个闭包。
我的尝试是:
for(var i = 0; i < 10; i++) {
setTimeout((function(i2){
return function() {
console.log(i2);
}
})(i), 1000);
}
所以我捕获了i
(在闭包中命名为i2
),但现在我使用了返回另一个函数并传递它。# EYZ4
现在谁在使用闭包,谁没有呢?
请注意,这两个解决方案都延迟在控制台上打印0到9,因此它们解决了最初的问题,但我们想了解这两个解决方案中哪一个使用闭包能够完成这个任务。