在for循环中使用onload时很奇怪

时间:2014-05-10 19:29:11

标签: javascript onload

我正在使用JavaScript和HTML画布制作游戏。 'onload'在没有for循环的情况下完美运行。但是“onload”在for循环中变得越来越不合理。但是,我想出了一个简单的解决方法来跳过这个问题。但我仍然好奇为什么。代码如下,解决方法如何:

我创建了一个对象:

function Monster() {
    this.image = new Image();
    this.ready = false;
}

并创建了一些(比方说两个)实例:

var monster = [];
for(var a = 0; a < 2; a++) {
    monster.push(new Monster());
}

当我尝试初始化这些对象时,它会失败:

for(n = 0; n < monster.length; n++) { //assume length is 2
    monster[n].image.onload = function() {
        monster[n].ready = true;   /* Problem raise up here, n has the same value as monster.length. 
                                      If length is 2, this line gonna run 2 times */
    };
    monster[n].image.src = 'images/m1.png';
}

但是,通过创建函数可以轻松解决此问题:

for(n = 0; n < monster.length; n++) {
    makeMonster(n);
}

var makeMonster = function(n) {
    monster[n].image.onload = function() {
        monster[n].ready = true;
    };
    monster[n].image.src = 'images/m1.png';
};

问题是,为什么?

1 个答案:

答案 0 :(得分:3)

onload函数是异步的,所以当它触发时,循环已经完成,n的值是它设置为持续的任何值。

您必须使用闭包在新作用域中锁定n变量的值,创建新函数也会创建此类作用域,或者像这样

for(n = 0; n < monster.length; n++) {
    (function(k) {
        monster[k].image.onload = function() {
            monster[k].ready = true;
        }
        monster[k].image.src = 'images/m1.png';
     })(n);
}
相关问题