They are all subtly different approaches.
for(var i = 0; i<array.length; i++){}
is the tried-and-true method; feels like C, works like C.
- Iterates over every array index, even those without a corresponding property/item.
- Works on any object supporting
.length
and properties with names [0..length); while it also works on sparsely-populated arrays an additional guard may be required.
- Unlike
forEach
, this allows the use of continue/break/return
as well as manual adjustment of the index from within the loop body, if such is ever required.
array.forEach(function(item, index){})
is the approach I prefer because it is often sufficient, feels cleaner, and is "lazy".
- Iterates over every array value/index that has an property.
- Implicitly implies a new function-scope each loop.
- While defined on Array.prototype it it can be used generally over array-like objects with
call/apply
.
- It has more overhead than
for..i++
(link stolen from James G.'s comment). However, this often doesn't matter and the relative performance difference will decrease as the work done in the body increases.
for (var index in array){}
should not be used when dealing with Array/sequence iteration.
- Iterates over all not-excluded-from-enumeration properties, traversing [prototype] as well
- Property names are iterated in an implementation-defined order2
Here is a 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 An example producing 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 and IE 10 iterate in ascending numerically; FF iterates in order inserted (for smaller ranges of values FireFox also sorts ascending numerically). Just don't use this approach for iterating a sequence and there won't be any problems like this.