The Convenience of Enhanced for

The for loop is arguably one of the most widely used constructs in C-like languages. Here’s an example of using the for loop to iterate over a list of names and print each element.

 const​ names = [​'Sara'​, ​'Jake'​, ​'Pete'​, ​'Mark'​, ​'Jill'​];
 
 for​(​let​ i = 0; i < names.length; i++) {
  console.log(names[i]);
 }

The output from this code is the expected listing of the names:

 Sara
 Jake
 Pete
 Mark
 Jill

That loop is very familiar but far from being simple—it has way too many moving parts. We first had to initialize the variable i, then set its upper bound, pause to grimace, wonder if it should be < or <=, then decide between pre-increment and post-increment. The assault of the complexity continues within the loop—we have to access the element in the collection based on the value of the index variable i.

No doubt, the for loop is quite powerful and capable. We can use it to iterate in forward or reverse order, we can break out of the loop at any time, we can step in increments of 2, and so on. However, we use it for the common forward iteration most of the time, and that’s tedious.

Simple Iteration Over Elements

For straightforward iterations, the enhanced for loop is a better choice. Let’s convert the previous loop to use this newer facility.

 const​ names = [​'Sara'​, ​'Jake'​, ​'Pete'​, ​'Mark'​, ​'Jill'​];
 
 for​(​const​ name ​of​ names) {
  console.log(name);
 }

This code produces the same result as the previous one, but it needed far less typing and is easier to read as well. Unlike the index variable i in the traditional for loop, the variable name used in the enhanced loop is a constant. It also has block scope and directly represents the selected element in each iteration. This code is not only concise, it is less error prone as well—we will discuss this further later in this chapter—a simple solution for a simple problem.

We can use for...of on any object that is iterable—that is, any object that implements the [Symbol.iterator]() method—we’ll learn more about this in Implementing an Iterator.

Getting the Index

The traditional for loop forced us to use the index variable even if we did not care for it. The enhanced for loop directly gets us the desired element in each iteration, but it does not prevent us from getting the index. To access the index, first we have to use the entries() function; let’s explore that function first.

The entries() function of Array returns an iterator, which has the key plus the value. Let’s iterate over the iterator returned by entries to get a feel for it.

 const​ names = [​'Sara'​, ​'Jake'​, ​'Pete'​, ​'Mark'​, ​'Jill'​];
 
 for​(​const​ entry ​of​ names.entries()) {
  console.log(entry);
 }

The variable entry represents the elements returned by the entries() method in each step of the iteration. Printing its content reveals that entry has two pieces of information: an index and the value at that index in the original array. We can see this in the output:

 [ 0, 'Sara' ]
 [ 1, 'Jake' ]
 [ 2, 'Pete' ]
 [ 3, 'Mark' ]
 [ 4, 'Jill' ]

To get the index more conveniently while iterating over the array, we can use the enhanced for loop along with the facility to destructure arrays—we will explore destructuring in Chapter 6, Literals and Destructuring.

Let’s rewrite the example with enhanced for loop to get the index and the value while iterating.

 const​ names = [​'Sara'​, ​'Jake'​, ​'Pete'​, ​'Mark'​, ​'Jill'​];
 
 for​(​const​ [i, name] ​of​ names.entries()) {
  console.log(i + ​'--'​ + name);
 }

Instead of specifying only the name, we include the index variable i as well, but in an array. Then instead of iterating over names we iterate over the iterator returned by entries. Through each iteration, when the entries iterator provides an entry, the index and the value in the entry are destructured and placed into the variables i and name, respectively.

Here’s the output from the previous code:

 0--Sara
 1--Jake
 2--Pete
 3--Mark
 4--Jill

The enhanced for loop is the surefire replacement for the traditional for loop for simple iterations. It does not force us to deal with the index. Furthermore, even if we need the index, we don’t have to mess with the bounds or alter the index.

Again, unlike the variable i used in the traditional for loop, this variable i is immutable—that reduces the chances of errors in code.

The entries() method returns an iterator, but JavaScript relies on a special method of Symbol for iteration. Let’s dive into that new primitive type next.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.63.114