This question already has answers here:
Javascript infamous Loop issue? [duplicate]
(5个答案)
JavaScript closure inside loops – simple practical example
(44个回答)
5年前关闭。
我正在使用JavaScript和HTML画布制作游戏。 “加载”功能完美运行而无需for循环。但是“加载”在for循环中变得有问题且不合理。但是,我想出了一个简单的解决方法来跳过该问题。但是我仍然很好奇为什么。以下是代码以及解决方法:
我创建了一个对象:
并创建了几个(假设两个)实例:
当我尝试初始化这些对象时,它将失败:
但是,可以通过创建一个函数轻松解决此问题:
和:
问题是,为什么?
(5个答案)
JavaScript closure inside loops – simple practical example
(44个回答)
5年前关闭。
我正在使用JavaScript和HTML画布制作游戏。 “加载”功能完美运行而无需for循环。但是“加载”在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';
};
问题是,为什么?
最佳答案
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);
}