【问题标题】:sum index in JavaScript foreachJavaScript foreach 中的总和索引
【发布时间】:2011-08-09 08:04:29
【问题描述】:

在下面的代码示例中,我得到了一个奇怪的行为

var data = ['xxx', 'yyy'];
for (var i in data)
{
    var a = i;
    var b = data[i];
}

前两次迭代运行良好。我在i 中得到了索引"0""1",但随后它又循环了一次,现在i"sum"。这是设计使然还是这个额外的迭代用于什么?在我的情况下,结果总是空的,它弄乱了我的代码。有没有办法不做他的额外循环?

BR 安德烈亚斯

【问题讨论】:

  • 你过于简单化了。真正的代码是什么样子的?
  • 不,这不是“真正的”代码,但在这种情况下问题是一样的。

标签: javascript foreach


【解决方案1】:

看起来您(或您包含的其他代码)已在 Array 原型上添加了额外的属性。您应该做的是检查您正在迭代的对象是否实际上在 自身 上具有该属性,而不是在其原型上:

for (i in data) {
    if (data.hasOwnProperty(i)) {
        a = i;
        b = data[i];
    }
}

也就是说,您永远不应该在数组上使用for .. in。使用常规的for 循环。

更多信息请看这里:http://yuiblog.com/blog/2006/09/26/for-in-intrigue/

【讨论】:

  • 我想你已经明白了。我敢打赌,还有另一个库添加了 Array.prototype.sum,使得 for...in 迭代中断。
  • 来自 Wikipedia 关于此主题:“遍历数组的所有使用索引,包括数组对象的所有用户定义属性(如果有)。因此,在以下情况下使用带有数字索引的传统 for 循环可能会更好遍历数组。”
【解决方案2】:

您正在循环通过Array,而不是通过Object。对于数组,最好使用:

for (var i=0; i<data.length; i=i+1){
  /* ... */
}

在您的循环中,Array 对象的每个属性都被考虑在内。这使得数组的for ... in 循环更难以预测。在您的情况下,sum 似乎是一个属性(方法),已添加到代码中其他位置的 Array.prototype

还有更多方法可以遍历数组。参见例如this SO-question,或this one

只是为了好玩,一种更深奥的循环数组的方法:

Array.prototype.loop = function(fn){
  var t = this;
  return (function loop(fn,i){
   return i ? loop(fn,i-1).concat(fn(t[i-1])) : [];
  }(fn,t.length));
}
//e.g.
//add 1 to every value
var a = [1,2,3,4,5].loop(function(val){return val+1;});
alert(a); //=> [2,3,4,5,6]
//show every value in console
var b = [1,2,3,4,5].loop(function(val){return console.log(val), val;});

【讨论】:

  • 迭代 for...in 虽然不常见,但仍然是迭代数组的有效方法。
  • 按照规范你是正确的。无论如何,它在 Firefox 中运行顺利。
  • +1 来抵消 -1... 在数组上使用 for in 应该不被接受,所以这是一个很好的建议。但它并没有真正回答这个问题,即为什么会出现sum 变量。
  • @cwallenpole:我改写了我的答案。 @nickf:编辑了答案以给出i 的可能解释,最终结果为sum
  • @Kooilnc 我看到了。我摆脱了 -1。
【解决方案3】:

这是一种安全迭代的方法。

var data = ['xxx', 'yyy'];
for (var i = 0; i < data.length; i++)
{
    var a = i;
    var b = data[i];
}

你得到的是一个来自扩展 Array 对象的方法,我猜你正在使用一些类似的库 Array.prototype.sum = function () {...};

【讨论】:

    【解决方案4】:

    也许这样设置数据会更好:var data = {0:'xxx', 1:'yyy'};

    【讨论】:

      【解决方案5】:

      首先data是一个对象。尝试添加 console.log(a);和console.log(b);在你的循环中,你会看到。

      【讨论】:

        猜你喜欢
        • 2018-10-22
        • 1970-01-01
        • 2021-02-02
        • 2012-11-07
        • 1970-01-01
        • 2010-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多