Appearance
Iterable
You can traverse an Array using index-based loops, but you cannot use indexes to iterate through a Map or Set. To standardize collection types, the ES6 standard introduced a new iterable type, which includes Arrays, Maps, and Sets.
Collections with iterable types can be traversed using the new for ... of
loop.
To test if your browser supports the for ... of
syntax, run the following code:
javascript
let a = [1, 2, 3];
for (let x of a) {
}
console.log('Your browser supports for ... of');
// Directly run the test
Using for ... of
to Traverse Collections
You can use the for ... of
loop to iterate through collections as follows:
javascript
let a = ['A', 'B', 'C'];
let s = new Set(['A', 'B', 'C']);
let m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (let x of a) { // Iterate over Array
console.log(x);
}
for (let x of s) { // Iterate over Set
console.log(x);
}
for (let x of m) { // Iterate over Map
console.log(x[0] + '=' + x[1]);
}
You might wonder how the for ... of
loop differs from the for ... in
loop. The for ... in
loop, due to legacy reasons, actually iterates over the property names of an object. An Array is also an object, and each element's index is treated as a property.
When you manually add extra properties to an Array object, the for ... in
loop can yield unexpected results:
javascript
let a = ['A', 'B', 'C'];
a.name = 'Hello';
for (let x in a) {
console.log(x); // '0', '1', '2', 'name'
}
The for ... in
loop includes name
, but it does not include the Array's length
property.
On the other hand, the for ... of
loop completely fixes this issue by iterating only over the collection's elements:
javascript
let a = ['A', 'B', 'C'];
a.name = 'Hello';
for (let x of a) {
console.log(x); // 'A', 'B', 'C'
}
This is why the new for ... of
loop was introduced.
Using forEach
Method
A more efficient way is to use the built-in forEach
method available for iterables, which takes a function and automatically calls it on each iteration. For example, for an Array:
javascript
let a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
// element: points to the current element's value
// index: points to the current index
// array: points to the Array object itself
console.log(`${element}, index = ${index}`);
});
Note that the forEach()
method was introduced in the ES5.1 standard, so you should check if your browser supports it.
Set and Map with forEach
The Set behaves similarly to an Array, but since it has no indices, both the first two parameters of the callback function are the element itself:
javascript
let s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
console.log(element);
});
For a Map, the callback function's parameters are value
, key
, and the map itself:
javascript
let m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
console.log(value);
});
If you are not interested in some parameters, you can ignore them, as JavaScript function calls do not require consistent parameters. For example, if you only want to get the element from the Array:
javascript
let a = ['A', 'B', 'C'];
a.forEach(function (element) {
console.log(element);
});