我的JavaScript代码中的索引越界错误

时间:2013-02-01 23:10:16

标签: javascript arrays object closures settimeout

以下代码中存在错误:

generate: function() {
    var generated = [];
    for (var j = 0; j < objectDefinitions.length; j++) {
        var randomNumber;

        if (!objectDefinitions[j].restrictGeneration) {
            continue;
        }

        randomNumber = Math.random();

        if (randomNumber < objectDefinitions[j].probability) {
            generated.push(objectDefinitions[j].createObject());
            objectDefinitions[j].restrictGeneration = true;
            if (j > 5) {
            }
            setTimeout(function() {                 
                //console.log(j);
                objectDefinitions[j].restrictGeneration = false;
            }, objectDefinitions[j].cooldown);
        }
    }
    return generated;
}

当setTimeout“触发”时,变量j为6,这会导致数组索引超出范围异常,因为数组中只有6个项目。我真的不明白发生了什么,我已经在setTimeout之外检查了j,它从不是6,但它在声明之后似乎有所改变。谢谢你的帮助。

3 个答案:

答案 0 :(得分:1)

它读取的变量j是您在循环中使用的变量,因此它不会被“复制”。

setTimeout(
    (function(k){
        return function() {            
            objectDefinitions[k].restrictGeneration = false;
        };
    }(j))
, objectDefinitions[j].cooldown);

这样您j就会复制到k变量中。但是每次迭代循环都有一个k变量。

答案 1 :(得分:0)

你的空if语句执行(通过什么都不做),然后它移动到设置超时,j仍然大于5。

基本上,你应该在那一点退出,而不是继续在if语句之后执行更多代码,或者在那里发出一个else语句,这样如果j&gt;则不再执行代码。 5。

答案 2 :(得分:0)

这是由于闭包

您看到6的值,因为j++最后一次触发for循环的退出。因此,闭包现在的j为6.当setTimeout执行时(在for循环完成后,它将在generate: function() { var generated = []; for (var j = 0; j < objectDefinitions.length; j++) { handleIteration(generated, j); // Re-factor your code into a new function } return generated; } 循环执行关闭的背景。

您需要将此代码移动到自己的闭包中,这可以通过将其移动到自己的函数中来完成。类似的东西:

{{1}}