For var index in vs. forEach

In javascript, if I want to iterate over every element in an array, I have several ways to do it:

1.

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

      

2.

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

      

3.

for (var index in array){}

      

The first is generic, but if I'm feeling lazy, I want to use the second or third.

But I'm wondering if there is a difference between the two and in which situation should I choose which one?

+3


source to share


5 answers


These are all subtly different approaches.

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

is a proven method; feels like C, works like C.

  • Iterations over every index of the array, even those that don't have a corresponding property / element.
  • Works with any object that supports .length

    and properties named [0..length); while it also works in sparsely populated areas, additional protection may be required.
  • In contrast forEach

    , this allows for use continue/break/return

    as well as manual adjustment of the index from within the loop body, if ever required.

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

is the approach I prefer because it is often enough, it feels cleaner and "lazy" .

  • Iterates through all the values ​​/ array index that have the property.
  • A new scope function is implicitly implied for each loop.
  • As long as it is defined in Array.prototype, it can be used mostly on array-like objects with call/apply

    .
  • It has more overhead than it doesfor..i++

    (link stolen from James G.'s comment). However, this often does not matter, and the relative difference in performance will decrease as the work done in the body increases.

for (var index in array){}

should not be used when working with array / sequence iteration.

  • Iterate over all non-enumerated properties, walk through [prototype], and
  • Property names are repeated in implementation order 2



Here's a demo of some of the 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 An example of creating a different order of iterations 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 and IE 10 repeat ascending; FF iterates to insert (for smaller ranges, FireFox also sorts in ascending order). Just don't use this approach to repeat a sequence and there won't be such problems.

+4


source


The third one is a bad idea because it iterates over objects, not elements in the array (although you might mistake this for this, since the elements are properties (but there may be other properties)).

Here's another other question: Looping through an array in JavaScript



And helpful off-site discussion: http://javascriptweblog.wordpress.com/2011/01/04/exploring-javascript-for-in-loops/

And from Crockford: http://javascript.crockford.com/code.html#for%20statement

+1


source


Use 1 if you have a loop, not an iterator. The second option is the most common when you want to iterate over an array. This cannot be used to iterate over an array, so:

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

      

0


source


  • Will only work for arrays. You cannot traverse objects this way.
  • Will only work for arrays. Slower than # 1, but by creating a new scope function

    , you ensure that any asynchronous callbacks that contain your parameters index

    or item

    grab the current value as they go through the scope, not their final value.
  • Great for walking over objects as well as arrays. Slightly slower than # 1 when working with arrays. This can be dangerous because some naughty libraries like PrototypeJS add properties to the Array prototype, which means you end up with indices that don't actually represent the elements in the array. Don't use this if there is a chance your code will be used on the same page as the library that does it.

Another interesting difference occurs when your array contains "undefined" values. This is unusual in my experience, but it will make a difference. For example:

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

      

Approach # 1 shows indices 0, 1, 2, 3, 4, 5 showing undefined values ​​on 1, 2, 3 and 4.
Approaches # 2 and # 3 to index 0, 1, 2, 5 showing undefined values ​​at values 1 and 2.

0


source


The first is ok, since collections in javascript are indexed, and the third is in a loop between all unreferenced elements.

If order doesn't matter, you can try to improve performance like this:

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

      

0


source







All Articles