JavaScript - why shouldn't I use for…in statement to iterate arrays?
Recently someone told me not to use for...in
statement to iterate arrays. Can you tell me why?
Directly from the manual:
The
for...in
statement iterates over all enumerable properties of an object that are keyed by strings (ignoring ones keyed by Symbols), including inherited enumerable properties. While Array indexes are just enumerable properties with integer names, otherwise identical to general object properties, there is no guarantee thatfor...in
will return the indexes in any particular order.Because the order of iteration is implementation-dependent, iterating over an array may not visit elements in a consistent order. Therefore, it is better to use a
for
loop with a numeric index (orArray.prototype.forEach()
or thefor...of
loop) when iterating over arrays where the order of access is important.
The other answer is way too is uncessarily thorough. If you want to be a developer you need to get used to reading the documentation for things. At least the documentation for the actual language itself..
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
From my personal point of view, yeah it does seem logical to assume because of the "in" that you're iterating the items "in" the array, but this is designed for iterating the properties "in" an object, it was never made or meant for arrays even though they can be used, it's only because Arrays are also objects.
If you want to iterate over the values of an object including the values of an Array there's an alternate type of statement that of couse is the for...of statement
xxxxxxxxxx
let arr = ['a', 'b', 'c', 'd'];
for (val of arr) {
console.log(val);
}
The for...in
statement is not used to iterate arrays because it iterates over keys and properties.
It is also considered bad practice for iterating through arrays because of some use cases.
Example 1
Let's take a look at the code below:
xxxxxxxxxx
const array = [];
array[3] = 'A'; // causes array resize
for (let i = 0; i < array.length; ++i) {
console.log(array[i]); // prints each item including undefined
}
In this example for
loop prints each item including undefined
ones.
However, when we use for...in
statement, it will ignore the undefined
keys and display only the value under the index 3
.
xxxxxxxxxx
const array = [];
array[3] = 'A';
for (const key in array) {
console.log(`${key}: ${array[key]}`); // prints only array[3], ignores previous indexes
}
Example 2
JavaScript also has problems when you add something to the array prototype e.g:
xxxxxxxxxx
Array.prototype.x = 'D'; // x will be part of every array from now
Array.prototype.y = 'E'; // y will be part of every array from now
const array = ['A', 'B', 'C'];
for (const key in array) {
console.log(`${key}: ${array[key]}`); // x and y will be displayed here too as value of key
}
As you see the result is not as we expected.
Example 3
An array is an object that can be extended with additional fields
xxxxxxxxxx
const array = ['A', 'B', 'C'];
array.x = 'D';
array.y = 'E';
for (const key in array) {
console.log(`${key}: ${array[key]}`);
}