【问题标题】:Index out of bounds bug in my JavaScript code我的 JavaScript 代码中的索引越界错误
【发布时间】:2013-01-17 09:00:41
【问题描述】:

以下代码有错误:

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

【问题讨论】:

  • 我想知道这个问题是否有更好的标题,因为这对于新手js程序员来说似乎是一个很好的学习机会,应该找到这个问题!

标签: javascript arrays object closures settimeout


【解决方案1】:

这是由于闭包

您会看到 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;
}

【讨论】:

  • 是的,我确实认为这可能与范围/闭包有关,但由于某种原因,我对发生的事情感到非常困惑,我(错误地)认为 j 会被复制而不是参考。我通过使用 xavierm02 描述的匿名函数解决了这个问题,尽管如此谢谢你,但使用单独的函数可能更优雅。
【解决方案2】:

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

基本上,您应该在该点退出,而不是在 if 语句之后继续执行更多代码,或者在那里创建一个 else 语句,以便在 j > 5 时不再执行代码。

【讨论】:

  • 感谢您的回复,不幸的是,此时 j 永远不会 > 5。这很奇怪。
【解决方案3】:

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

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

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

【讨论】:

  • 非常感谢,我需要仔细研究一下,但代码运行良好
猜你喜欢
  • 2014-06-06
  • 2015-03-22
  • 1970-01-01
  • 2022-08-24
  • 2013-10-13
  • 2015-01-10
  • 2014-01-27
相关资源
最近更新 更多