Categories
JavaScript JavaScript Basics

Why Should We Use the JavaScript For-Of Loop?

Spread the love

Since ES6 we have the for...of loop. It’s a very useful loop that can do a lot more than regular for loops. In this article, we’ll look at why the for...of loop is useful for developers and whether the performance is good enough to replace the for loop.

The for...of loop lets us loop through arrays, array-like objects, and user-defined iterables. It lets us loop through all of them without using different kinds of methods and loops.

For example, we can create a for...of loop to loop through arrays as follows:

const arr = [1, 2, 3];

for (const a of arr) {  
  console.log(a);  
}

The loop will produce the following output:

1  
2  
3

Where the for...of loop shines is the ability to iterate through array-like objects like NodeLists and our own iterable objects. For example, if we have the following HTML:

<p>  
  foo  
</p>  
<p>  
  bar  
</p>  
<p>  
  baz  
</p>

then we can use the following JavaScript

const nodeList = document.querySelectorAll('p');

for (const element of nodeList) {  
  console.log(element.textContent.trim());  
}

Then we get the following logged:

foo  
bar  
baz

With the for...of loop we don’t have to write out the indexes like with a regular for loop to iterate through NodeList, which is the only alternative since it’s not an array, but an array-like object.

Also, we can iterate user-defined iterable objects like generators and iterable objects with it. For example, given the following generator:

function* generator() {  
  yield 1;  
  yield 2;  
  yield 3;  
}

We can use the for...of loop to loop through it as follows:

for (let a of generator()) {  
  console.log(a);  
}

Then we get:

1  
2  
3

Furthermore, we can define our own iterable object. As long as it has the Symbol.iterator method, we can loop through it with the for...of loop. Given that we have:

const iterableObj = {  
  *[Symbol.iterator]() {  
    yield 1;  
    yield 2;  
    yield 3;  
  }  
}

We can loop through it with:

for (let a of iterableObj) {  
  console.log(a);  
}

The for...of also has no problem looping through new objects like Set s and Map s:

const set = new Set([1, 1, 2, 2, 2, 3, 5, 4, 3]);

for (const value of set) {  
  console.log(value);  
}

Then we get:

1  
2  
3  
5  
4

Likewise, we can loop through maps:

const map = new Map([  
  ['a', 1],  
  ['b', 2],  
  ['c', 3]  
]);

for (const value of map) {  
  console.log(value);  
}

Also, we can loop through strings with it. For instance, given that we have the following string:

const str = 'foo';

We can loop through each character as follows:

for (let char of str) {  
  console.log(char);  
}

Then we get:

f  
o  
o

As we can see, it’s very useful for looping through anything that can be looped through.

Performance

We can test this by looping through a number array with 10000 entries. The array is constructed as follows:

let arr = [];  
for (let i = 1; i <= 10000; i++) {  
  arr.push(i);  
}

To test the performance of each loop, we use the console.time and console.timeEnd methods available in most modern browsers.

With the forEach method of an array, we get that it takes 840.8779296875ms to loop through each entry with the forEach method of an array.

With the for...of loop, it takes 843.972900390625ms to loop through each entry of the same array.

Finally, with a plain for loop, it takes 841.210205078125ms seconds to loop through 10000 numbers.

With length caching as we do below:

const len = arr.length;  
for (let i = 0; i < len; i++) {  
  console.log(arr[i]);  
}

It’s even faster at 593.16796875ms.

As we can see, the plain for loop is much faster. However, for looping through small amounts of data, we can live with the slightly slower performance. Also, we don’t have to write any extra code to loop through other kinds of iterable objects like Map s and Set s.

This means that for non-array iterable objects, the for...of loop is still better for looping through these kinds of things. Less code means less processing time is needed.

However, for arrays, if we loop through an array with lots of entries, then the plain old for loop is probably a better choice.

Should we use the for…of loop?

From what we looked at, the for...of loop is good for anything other than large arrays. It can loop through many more kinds of objects than other loops or the array’s forEach method out of the box.

It’s designed to be more flexible and clean than other loops.

Also, we don’t have to worry about what we loop through as long as they’re iterable, which isn’t the case with other loops.

The only thing that it’s not good at is looping through large arrays. In that case, use the for loop with the array length cached.

Leave a Reply

Your email address will not be published. Required fields are marked *