在for循环和词法环境中闭包 [英] Closures in a for loop and lexical environment

查看:122
本文介绍了在for循环和词法环境中闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简单情况:我想加载几个具有通用名称和后缀的图片,例如: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 执行时,不是在将它分配给 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆