for for var index in vs. forEach

时间:2014-09-10 21:36:21

标签: javascript loops for-loop iterator iteration

在javascript中,如果我想循环遍历数组中的每个元素,我有几种方法可以做到这一点:

1

for(var i =0; i<array.length; i++){}

2

array.forEach(function(item, index){});

3

for (var index in array){}

第一个是常见的,但如果我感到懒惰,我想使用第二个或第三个。

但是我想知道他们之间是否有任何区别,我应该选择哪种情况?

5 个答案:

答案 0 :(得分:5)

他们都是略有不同的方法。

for(var i = 0; i<array.length; i++){}是经过验证的方法;感觉像C,像C一样。

  • 迭代每个数组索引,即使没有相应属性/项目的那些
  • 适用于任何支持.length的对象和名称为[0..length)的属性;虽然它也适用于人口稀少的阵列,但可能需要额外的防护。
  • forEach不同,这允许使用continue/break/return以及在循环体内手动调整索引,如果需要的话。

array.forEach(function(item, index){})是我更喜欢的方法,因为它通常足够,感觉更干净,而且是"lazy"

  • 遍历具有属性的每个数组值/索引
  • 隐含地暗示每个循环的新功能范围。
  • 虽然在Array.prototype上定义,但它通常可以用于call/apply的类似数组的对象。
  • 它有more overhead than for..i++(从James G.的评论中窃取的链接)。然而,这通常无关紧要,随着身体工作的增加,相对性能差异减少
在处理数组/序列迭代时,

for (var index in array){} 不应该


这是demonstration of some differences

var array = [];
array[0] = 1;
array[2] = 2;  // Note that `1 in array` is false as it was never set
array.hello_world = 3;

var a = 0;
for(var i = 0; i<array.length; i++){
    a += array[i]
}
// -> NaN; because array[1] was undefined
console.log("index: " + a);

var b = 0;
array.forEach(function (v, i) {
    b += v;
});
// -> 3; because v was never undefined (as array[1] was skipped)
console.log("forEach: " + b);

var c = 0;
for (var p in array) {
    c += array[p];
}
// -> 6; picked up "hello_world" but didn't pick up missing "1" property
console.log("for..in: " + c); 

2 一个产生different iteration order between browsers的例子:

var a = [];
for (var i = 100000; i > 0; i -= 1000) { a[i] = i; }

var s = "";
for (var p in a) { s += p + ",";  }
console.log(s);

Chrome和IE 10以数字递增的方式迭代; FF按插入顺序迭代(对于较小范围的值,FireFox也按数字递增排序)。只是不要使用这种方法来迭代序列,就不会出现这样的问题。

答案 1 :(得分:1)

第三个是一个坏主意,因为它遍历对象属性,而不是遍历数组中的项目(尽管你可以将其误认为,因为项目是属性(但也可以有其他属性))

以下是相关的其他SO问题:Loop through an array in JavaScript

一个有用的场外讨论:http://javascriptweblog.wordpress.com/2011/01/04/exploring-javascript-for-in-loops/

来自Crockford:http://javascript.crockford.com/code.html#for%20statement

答案 2 :(得分:0)

当你有循环而不是迭代器时使用1。当您想要遍历数组时,第二个选项是最常见的。这个不应该用于迭代数组,这就是为什么:

x = []
> []
x.a = 1;
> 1
x[0] = 2
> 2
for (var i in x) console.log(i);
> 0
> a

答案 3 :(得分:0)

  1. 仅适用于数组。你无法以这种方式遍历对象。
  2. 仅适用于数组。比#1慢,但通过创建新的function范围,您可以确保包含indexitem参数的任何异步回调都捕获当前值通过范围而不是最终值。
  3. 适用于遍历对象和数组。在处理数组时,比#1略慢。 这可能很危险,因为像PrototypeJS这样的淘气库会为Array原型添加属性,这意味着你最终会得到实际上并不代表数组中项目的索引。如果您的代码有可能与执行此操作的库在同一页面上使用,请不要使用此功能。
  4. 如果数组中有“未定义”值,则会出现另一个有趣的差异。根据我的经验,这种情况并不常见,但它会产生影响。例如:

    var array = [0, undefined, 2, 3];
    array[2] = undefined;
    delete array[3];
    array[5] = 5;
    

    方法#1命中索引0,1,2,3,4,5,在1,2,3和4处显示未定义的值。
    方法#2和#3命中索引0,1,2,5,在1和2处显示未定义的值。

答案 4 :(得分:0)

第一个是好的,因为javascript中的集合是可索引的,第三个是在没有引用的情况下在所有元素之间循环。

如果订单无关紧要,您可以尝试使用此功能来提高性能:

var i = list.length;
while (i--)
{
   var item = list[i];
   // manipulate item           
}