Signup/Sign In
Ask Question
Not satisfied by the Answer? Still looking for a better solution?

Why is using “for…in” for array iteration a bad idea?

I've been advised not to utilize for...in with arrays in JavaScript. Why not?
by

2 Answers

aashaykumar
There are three reasons why you shouldn't use for..in to iterate over array elements:

1. for..in will loop over all own and inherited properties of the array object which aren't DontEnum; that means if someone adds properties to the specific array object (there are valid reasons for this - I've done so myself) or changed Array.prototype (which is considered bad practice in code which is supposed to work well with other scripts), these properties will be iterated over as well; inherited properties can be excluded by checking hasOwnProperty(), but that won't help you with properties set in the array object itself

2. for..in isn't guaranteed to preserve element ordering

3. it's slow because you have to walk all properties of the array object and its whole prototype chain and will still only get the property's name, ie to get the value, an additional lookup will be required
sandhya6gczb
The for-in statement by itself is not a "bad practice", however, it can be misused, for example, to iterate over arrays or array-like objects.

The purpose of the for-in statement is to enumerate over object properties. This statement will go up in the prototype chain, also enumerating over inherited properties, a thing that sometimes is not desired.

Also, the order of iteration is not guaranteed by the spec., meaning that if you want to "iterate" an array object, with this statement you cannot be sure that the properties (array indexes) will be visited in the numeric order.

For example, in JScript (IE <= 8), the order of enumeration even on Array objects is defined as the properties were created:

var array = [];
array[2] = 'c';
array[1] = 'b';
array[0] = 'a';

for (var p in array) {
//... p will be "2", "1" and "0" on IE
}

Also, speaking about inherited properties, if you, for example, extend the Array.prototype object (like some libraries as MooTools do), that properties will be also enumerated:

Array.prototype.last = function () { return this[this.length-1]; };

for (var p in []) { // an empty array
// last will be enumerated
}

As I said before to iterate over arrays or array-like objects, the best thing is to use a sequential loop, such as a plain-old for/while loop.

When you want to enumerate only the own properties of an object (the ones that aren't inherited), you can use the hasOwnProperty method:

for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
// prop is not inherited
}
}

And some people even recommend calling the method directly from Object.prototype to avoid having problems if somebody adds a property named hasOwnProperty to our object:

for (var prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
// prop is not inherited
}
}

Login / Signup to Answer the Question.