我正在使用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';
};
问题是,为什么?
答案 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);
}