为什么我只能看到使用此JavaScript代码加载的最后一个图像?
下面的代码片段旨在循环遍历数组(包含4个对象);每一次迭代都会产生一张卡片的图像。经过4次迭代后,应该有4张卡片并排排列 问题:仅显示最终图像(即myHeroCards[3].image的元素)。警报框按顺序显示每次迭代的“0”、“1”和“2” 相关帖子提到了使用“for循环”单步遍历数组的问题;但我认为这不是问题所在,因为我可以通过将为什么我只能看到使用此JavaScript代码加载的最后一个图像?,javascript,arrays,function,for-loop,closures,Javascript,Arrays,Function,For Loop,Closures,下面的代码片段旨在循环遍历数组(包含4个对象);每一次迭代都会产生一张卡片的图像。经过4次迭代后,应该有4张卡片并排排列 问题:仅显示最终图像(即myHeroCards[3].image的元素)。警报框按顺序显示每次迭代的“0”、“1”和“2” 相关帖子提到了使用“for循环”单步遍历数组的问题;但我认为这不是问题所在,因为我可以通过将x替换为0-3来显示任何给定的图像 我怀疑onload是如何工作的,循环语句是如何计算的,但我对细节感到困惑 function startingCardLayou
x
替换为0-3来显示任何给定的图像
我怀疑onload是如何工作的,循环语句是如何计算的,但我对细节感到困惑
function startingCardLayout(){
var nextHeroCard=0;
var x=0;
for (i=0;i<=2;i++){
myHeroCards[x].image.onload = function (){ctx.drawImage(myHeroCards[x].image,(xFirstCol+(x*xColInc)),100,xCardSize,yCardSize);}
alert(x);
x=x+1;
}
}
功能启动卡片布局(){
var-nextHeroCard=0;
var x=0;
对于(i=0;i,您将为这些数组元素中的每个元素分配一个此处定义的函数:
function () {
ctx.drawImage(myHeroCards[x].image,
(xFirstCol+(x*xColInc)),
100,xCardSize,yCardSize
);
}
这引用了函数外部定义的变量x
。这意味着当您在for循环中更改变量x
时,这些函数将引用x
的新值,而不是旧值。这解释了为什么您只看到最后一幅图像:所有图像都在exac处绘制t相同的位置,并且只有最后一个(位于顶部的位置)它还解释了为什么您在循环中看到正确的x
值,以及为什么在硬编码数字时它可以工作-在循环中,一切都很好,但在循环完成后,您创建的所有函数都共享相同的x
值
为了解决这个问题,您可以使用这种技术,它创建变量x
的本地副本:
myHeroCards[x].image.onload = function(x) {
return function () {
ctx.drawImage(myHeroCards[x].image,
(xFirstCol+(x*xColInc)),
100,xCardSize,yCardSize
);
}
} (x);
这里,函数内部的变量x
是函数外部变量x
当前值的新副本
一般来说,如果您在JavaScript中使用循环,并且希望在循环中创建一些函数,这些函数引用在循环过程中更改的内容(这里是x
,但更一般地说,类似于循环计数器),您可能需要使用双嵌套函数习惯用法:
var thingy = function(values, i, care, about) {
return function() {
// Code that uses values I care about
}
} (values, i, care, about);
您正在为这些数组元素中的每个元素分配一个此处定义的函数:
function () {
ctx.drawImage(myHeroCards[x].image,
(xFirstCol+(x*xColInc)),
100,xCardSize,yCardSize
);
}
这引用了函数外部定义的变量x
。这意味着当您在for循环中更改变量x
时,这些函数将引用x
的新值,而不是旧值。这解释了为什么您只看到最后一幅图像:所有图像都在exac处绘制t相同的位置,并且只有最后一个(位于顶部的位置)它还解释了为什么您在循环中看到正确的x
值,以及为什么在硬编码数字时它可以工作-在循环中,一切都很好,但在循环完成后,您创建的所有函数都共享相同的x
值
为了解决这个问题,您可以使用这种技术,它创建变量x
的本地副本:
myHeroCards[x].image.onload = function(x) {
return function () {
ctx.drawImage(myHeroCards[x].image,
(xFirstCol+(x*xColInc)),
100,xCardSize,yCardSize
);
}
} (x);
这里,函数内部的变量x
是函数外部变量x
当前值的新副本
一般来说,如果您在JavaScript中使用循环,并且希望在循环中创建一些函数,这些函数引用在循环过程中更改的内容(这里是x
,但更一般地说,类似于循环计数器),您可能需要使用双嵌套函数习惯用法:
var thingy = function(values, i, care, about) {
return function() {
// Code that uses values I care about
}
} (values, i, care, about);