JavaScript的for...in循环如何处理多维数组?

6

我在尝试使用JavaScript编程时,通过for...in循环遍历多维数组时发现了一些奇怪的行为(至少对我来说是这样)。以下是我的代码:

<script type="text/javascript">
  var arr = [['a', 'b'], ['c','d']];

  var first='';

  for (var singleArray in arr) {
    first += ' ' + singleArray[0] + ' ' + singleArray[1];
  }

  var second = '';
  for (var i=0;i<arr.length; i++) {
    second += ' ' + arr[i][0] + ' ' + arr[i][1];
  }

  console.log('First: ', first);
  console.log('Second: ', second);
</script>

输出结果为:
First: 0 undefined 1 undefined
Second: a b c d

我预计第一和第二个将是相同的。您能否请解释一下我错过了什么?
注意:请不要建议通过jQuery或其他方式迭代数组。我没有编码问题,我只是对这种特定情况感到好奇。

1
当函数没有使用forEach时,它不应该被命名为forEach。例如:arr.forEach(function(is) { is.forEach( function (his) { console.log(his) } ) } );是正确的做法。 - Cris Stringfellow
@CrisStringfellow,我也觉得这个问题的标题有误导性,因为我正在寻找关于forEach循环的信息。那么这个问题的标题应该是什么? - Anderson Green
3个回答

10

Erick Mickelsen提出了一些很好的观点,总结一下:

  1. for (... in ...)循环遍历对象属性。
  2. 在Javascript中,array是一个对象,因此可以使用它来迭代数组。但这样做会更慢,一般不建议这样操作(详见原因)。
  3. 它遍历的是属性而不是值,这意味着返回的是索引而不是数组的值(当你有关联数组时可能会很方便)。
  4. 问题中的示例可以使用for (... in ...)循环解决。

如下所示:

var third = '';
for (var arrayIndex in arr) {
  third += ' ' + arr[arrayIndex][0] + ' ' + arr[arrayIndex][1];
}
在关联数组的示例中,for (... in ...)循环非常方便:
var person = [];
person["id"] = 1;
person["born"] = 2009;
person["favourite_meal"] = "chicken"; 

var fourth = '';
for (var arrayIndex in person) {
  fourth += ' ' + person[arrayIndex];
}

在JavaScript中,不使用“关联数组”这个术语。你第二个例子展示的事实是数组除了是数组之外还是对象,并且for...in循环遍历键。最好在第一行使用var person = {};,就像你在第二点中所说的那样。 - Heretic Monkey

1

嗯,但我看过几次并验证了单维数组中的 for (... in ...) 的工作方式。这是偶然的吗? - Jan Zyka
@Jan:它适用于数组,但仍会迭代属性名称/索引,而不是值。但要小心,因为它会迭代所有属性,而不仅仅是索引,包括添加到Array.prototype的函数。JavaScript的for/in确实不是为数组设计的,只是碰巧可以工作(有点)。 - Matthew Crumley
刚刚发现使用数组可以正常工作,但这里的区别在于它不返回值,而是返回索引... - Jan Zyka
Eric,除了w3schools之外,你能否链接到其他资源?提到for(...in...)而不提hasOwnProperty是有害的。http://bonsaiden.github.com/JavaScript-Garden/#object.forinloop - Yahel

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接