在for循环和词法环境中闭包 [英] Closures in a for loop and lexical environment
问题描述
简单情况:我想加载几个具有通用名称和后缀的图片,例如:image0.png,image1.png,image2.png ... imageN.png
Simple case: I want to load several images which have a common name and a suffix, e.g: image0.png, image1.png, image2.png ... imageN.png
我使用一个简单的for循环:
I'm using a simple for loop:
var images = [];
for (var i=1; i<N; i++) {
images[i] = new Image();
images[i].onload = function () {
console.log("Image " + i + " loaded");
};
images[i].src = "image" + i + ".png";
}
我在控制台中得到的是:
What I'm getting in the Console is:
Image N loaded
Image N loaded
Image N loaded
...
Image N loaded
但我想要的应该是这样:
But what I want should be like this:
Image 0 loaded
Image 1 loaded
Image 2 loaded
...
Image N loaded
为什么会发生这种情况?
如何获得我想要的行为?
Why is this happening? How can I get my desired behavior?
推荐答案
i $ c $当函数执行时,不是在将它分配给
onload
时,函数内部的函数c>当你的 onload
函数触发时,你的for循环已经完成了,所以他们看到的最终值 N
。
The i
inside your function is evaluated when the function is executed, not when you assign it to onload
. Your for loop has already completed by the time any of your onload
functions fire, so all of them see the final value N
.
要捕获 i
的当前值,需要将其作为参数传递给另一个函数,它可以被捕获为一个局部变量:
To capture the current value of i
, you need to pass it as a parameter to another function where it can be captured as a local variable:
function captureI(i) {
return function () {
console.log("Image " + i + " loaded");
};
}
var images = [];
for (var i=1; i<N; i++) {
images[i] = new Image();
images[i].onload = captureI(i);
images[i].src = "image" + i + ".png";
}
这是因为每次调用 captureI
,为
captureI
的实例创建一个新的局部变量。实际上,你创建了 N
个不同的变量,每个 onload
函数捕获变量的不同实例。
This works because every time you call captureI
, a new local variable is created for that instance of captureI
. In essence, you are creating N
different variables and each onload
function captures a different instance of the variable.
这篇关于在for循环和词法环境中闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!