Difference between for...of & for...in
Bothfor...in
andfor...of
statements iterate over something. The main difference between them is in what they iterate over.
Thefor...in
statement iterates over the enumerable properties of an object, in an arbitrary order.
Thefor...of
statement iterates over data that iterable object defines to be iterated over.
The following example shows the difference between afor...of
loop and afor...in
loop when used with anArray
.
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
let iterable = [3, 5, 7];
iterable.foo = 'hello';
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // logs 0, 1, 2, "foo"
}
}
for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}
Let us look into the above code step by step.
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
let iterable = [3, 5, 7];
iterable.foo = 'hello';
Every object will inheritobjCustom
property and every object that is anArray
will inheritarrCustom
property because of adding those properties toObject.prototype
andArray.prototype
. The objectiterable
inherits propertiesobjCustom
andarrCustom
because of inheritance and the prototype chain.
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}
This loop logs only enumerable propertiesofiterable
object, in original insertion order. It doesn't log array elements 3
, 5
, 7
orhello
because those are not enumerable properties. But it logs array indexes as well asarrCustom
andobjCustom
, which are. If you're not sure why the properties are iterated over, there's a more thorough explanation of howarray iteration and for...in
work.
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // logs 0, 1, 2, "foo"
}
}
This loop is similar to the first one, but it useshasOwnProperty()
to check, if the found enumerable property is object's own (not inherited). And if it is, the property is logged. Properties0
,1
,2
andfoo
are logged because they are own properties (not inherited). PropertiesarrCustom
andobjCustom
are not logged because they are inherited.
for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}
This loop iterates and logs values that iterable
as an iterable object defines to be iterated over, which are array elements 3
, 5
, 7
and not any of object's properties.