Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should forEach be preferred over regular iterators?

Tags:

I was reading airbnb javascript guide. There is a particular statement, that says:

Don’t use iterators. Prefer JavaScript’s higher-order functions instead of loops like for-in or for-of.

The reason they give for the above statement is:

This enforces our immutable rule. Dealing with pure functions that return values is easier to reason about than side effects.

I could not differentiate between the two coding practices given:

    const numbers = [1, 2, 3, 4, 5];      // bad     let sum = 0;     for (let num of numbers) {      sum += num;     }     sum === 15;      // good     let sum = 0;     numbers.forEach((num) => {      sum += num;     });      sum === 15; 

Could anyone explain, why should forEach be preferred over regular for loop? How does it really make a difference? Are there any side effects of using the regular iterators?

like image 405
Jatt Avatar asked Mar 22 '18 05:03

Jatt


People also ask

Which is better iterator or forEach?

Difference between the two traversalsIn for-each loop, we can't modify collection, it will throw a ConcurrentModificationException on the other hand with iterator we can modify collection. Modifying a collection simply means removing an element or changing content of an item stored in the collection.

Why is forEach better than for loop?

forEach LoopIt is faster in performance. It is slower than the traditional loop in performance.

What is the advantage of using forEach over traditional for loop *?

The advantage of the for-each loop is that it eliminates the possibility of bugs and makes the code more readable. It is known as the for-each loop because it traverses each element one by one. The drawback of the enhanced for loop is that it cannot traverse the elements in reverse order.

Which is faster forEach or iterator in Java?

In this case, iterator is more efficient because of its fail-fast property.


2 Answers

This reasoning in Airbnb style guide applies to array methods that are used for immutability, which are filter, map, reduce, etc. but not forEach:

This enforces our immutable rule. Dealing with pure functions that return values is easier to reason about than side effects.

So the comparison is more like:

// bad let sum = 0; for (let num of numbers) {  sum += num; } sum === 15;  // bad let sum = 0; numbers.forEach((num) => {  sum += num; });  sum === 15;  // good const sum = numbers.reduce((num, sum) => sum += num, 0);  sum === 15; 

Generally, for > forEach > for..of > for..in in terms of performance. This relationship is uniform in almost all engines but may vary for different array lengths.

forEach is the one that was significantly improved in latest Chrome/V8 (almost twice, based on this synthetic test):

Since all of them are fast, choosing less appropriate loop method just because of performance reasons can be considered preliminary optimization, unless proven otherwise.

The main benefits of forEach in comparison with for..of is that the former be polyfilled even in ES3 and provides both value and index, while the latter is more readable but should be transpiled in ES5 and lower.

forEach has known pitfalls that make it unsuitable in some situations that can be properly handled with for or for..of:

  • callback function creates new context (can be addressed with arrow function)

  • doesn't support iterators

  • doesn't support generator yield and async..await

  • doesn't provide a proper way to terminate a loop early with break

like image 117
Estus Flask Avatar answered Sep 27 '22 22:09

Estus Flask


That makes no sense. forEach should never be preferred. Yes, using map and reduce and filter is much cleaner than a loop that uses side effects to manipulate something.

But when you need to use side effects for some reason, then for … in and for … of are the idiomatic loop constructs. They are easier to read and just as fast, and emphasise that you have a loop body with side effects in contrast to forEach which looks functional with its callback but isn't. Other advantages over forEach include that you can use const for the iterated element, and can use arbitrary control structures (return, break, continue, yield, await) in the loop body.

like image 33
Bergi Avatar answered Sep 27 '22 23:09

Bergi