1

以下代码中存在错误:

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,但它似乎在声明后发生了变化。谢谢你的帮助。

4

3 回答 3

1

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

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

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

于 2013-02-01T23:14:45.857 回答
0

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

基本上,你应该在那个时候退出,而不是在 if 语句之后继续执行更多代码,或者在那里创建一个 else 语句,这样如果 j > 5 就不会执行更多代码。

于 2013-02-01T23:15:06.733 回答
0

这是由于关闭

您会看到6因为j++最后一次运行触发 for 循环退出的值。因此,该闭包现在的 aj为 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;
}
于 2013-02-01T23:56:12.413 回答