以下代码片段用于遍历数组(包含4个对象);每次迭代都应该产生卡片的图像。经过4次迭代后,每行应该有4张卡。
问题:只显示最终图像(即myHeroCards [3] .image的元素)。警报框按顺序显示每次迭代:" 0"," 1",2"。
相关帖子指的是使用" for循环的问题"通过一个数组;但我不认为这是问题所在,因为我可以通过将{% endif %}
替换为0-3来显示任何给定的图像。
我怀疑与onload如何工作以及如何评估循环语句的交互,但我对这些细节感到困惑。
x
答案 0 :(得分:0)
您为这些数组元素分配了一个定义的函数:
function () {
ctx.drawImage(myHeroCards[x].image,
(xFirstCol+(x*xColInc)),
100,xCardSize,yCardSize
);
}
这引用了变量x
,它是在函数外部定义的。这意味着当您更改for循环中的变量x
时,这些函数将引用x
的 new 值而不是旧值。这就解释了为什么你只能看到最后一张图像:所有图像都在完全相同的位置绘制,只有最后一张图像(顶部的图像)显示出来。它还解释了为什么你在循环中看到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);