Understanding JavaScript For Loops

Note: This post is work-in-progress learning-note and still in active development and updated regularly.

In JS programming, like in other programming languages, there would be a need to do certain task repeatedly, for example to run a block of code to perform repetitive tasks. JS loops offer easy way to perform same task repetitively. There are different kinds of loops but all do same thing: repeat certain actions for a number of times.

The MDN Document list different kinds of Loops & Iterations. In our previous learning post we discussed Conditional Statements to perform certain tasks repeatedly based on true or false return of specified conditions.  While the conditional statements are run only once, the while and do..while loop execute multiple times as long as the conditions evaluates true. In our previous learning-note post: Learning JavaScript While and Do..While Loops, we discussed while and do..while statements with some use case examples, together with using the break/continue, and label statements.

In this post, other common types of JS loops:the for statement, including the for..in and for..of statements will be discussed with some use case examples.

The For Statement

The for statement is fundamental to JS programming. To quote from the MDN – “the for statement creates a loop that consists of three optional expressions, enclosed in parentheses and separated by semicolons, followed by a statement (usually a block statement) to be executed in the loop“.

Basic Syntax

A for loop executes a task multiple times until a specified condition is evaluated false.

//basic syntax
for (initialization; condition; incrementExpression) {
   statement; //code block
   ..
}

The for statement syntax consists of the following three expressions:

  • Initialization: It is an expression that is typically used to initialize a loop counter variable. This expression can also be used to declare new variables with var, let or const keyword.
  • Condition: It is an expression to be evaluated before each loop iteration. If this expression is evaluated true statement block (body of code) is executed. If the condition returns false, statements are not executed and loop terminates. If the conditions are omitted, it is evaluated as true.
  • Statement: The statement (body of code) to be executed when the condition returns true. If a loop has multiple statements, then they must be enclosed within ({ ..}) as block statement. If there are no statements within a loop, an empty statement (;) is used.
  • Increment Expression: This is also known as final expression, which is executed at the end of each iteration. This is generally used to update or increment the counter variable. This step occurs before the next evaluation of the condition.
Example

Lets understand these expression using a simple example:

//initialize for statement with 4 iterations
for (let i = 0; i < 3; i++) {
 //print each iteration to the console
  console.log(i); 
}
//OUTPUT
0
1
2

In the example above, the for loop initialized with let i = 0 (initialization step) meaning the loop starts at 0. The loop condition statement is defined as i < 3, meaning that as long as i is less than 3 the loop executes – prints the value of i to the console (line 4). The final or increment expression i++ runs after each pass through the loop. The console prints out (line 7-9) starting 0 and terminates when i equals 3 but NOT including the value of 3.

Step Expression Description
initialization i = 0 Executes once upon entering the loop.
condition i < 3 Checked before every loop iteration, if false the loop terminates.
increment i++ Executes after the statement block  on each iteration, but before the condition check.
statement console.log(i) Runs again and again while the condition is true

The above table (adopted from The Modern JavaScript Tutorial) illustrates each step, expression and action in a typical loop iteration.

Understanding Expression Parameters

Initialization

This is the first expression in a loop and it is essential to begin a loop with initialization expression. A variable is declared and/or initialized at this step.

//initialize var outside loop
let i = 0;
//initilialize within a loop
for(i = 0; condition; incrementExpression) {
   statements;
   ..
}

In the example above, variable i is declared with let keyword and assigned a value of 0. Most commonly used variable name in such a for loop is i (which means iteration) but it can be anything, for example a or x etc.

This variable is also known as counter variable, can be declared right in the loop, a process called “inline” as well as outside the loop (line 1). The inline declared variables are visible only inside the loop. Lets examine this process below with an example.

//inline assignment expression
for (let i = 0; i < 3; i++) {
  console.log(i); // => 0, 1, 2
}
console.log(i); // =>ReferenceError: i is not defined

//initialize var outside the loop
let i = 0;
//use existing var
for (i = 0; i < 3; i++) {
  console.log(i); // => 0, 1, 2
}
console.log(i); // => 3

In the example above (adopted from The Modern JavaScript Tutorial), the i variable is declared and assigned a value of 0 right in the loop (line 2). Such inline variables are visible inside the loop only (line 3), when accessed from outside the loop, it throws a var not defined ReferenceError (line 5).

On the other hand, if var is declared outside the loop, value of i can be accessed outside of the loop as shown in line 8-13. In this example, var i is declared outside the loop (line 8) and value of i is assigned to 0 inside the for loop (line 10). Now, with the same condition, increment and loop body statement (lines: 10-11), value of i can be accessible from outside the loop, because the variable was declared outside the loop.

Condition

The condition expression evaluates true or false. As long as the condition returns true, statement block is executed. Once the condition is evaluated false, execution terminates and moves to next part of the code.

//initialize var 
let i = 0;
//define loop condition
for(i = 0; i < 3; incrementExpression) {
   statements;
   ..
}

Continuing our earlier example, where var i was initialized to 0.  Here a condition for executing the loop is set as i < 3 which means that as long as value of i is less than 3 (excluding 3), the condition returns true. When its value is 3 or more the condition evaluates false and execution of loop statement terminates.

Increment Expression

The increment Expression is run after each iteration. This is often used to increase or decrease the value of variable i.e. i in our example. Revisiting our earlier example, lets increase the the value of i by one as shown below:

//initialize var 
let i = 0;
//define loop condition
for(i = 0; i < 3; i++) {
   statements;
   ..
}

In the example above, the initialization and condition blocks are initialized previously. To increase the value i by one, it looks like i + 1 with i = i + 1. Its shorthand form is i++,  which is commonly used in most for loops.

For example, if we wanted to decrease the value of i by one after each iteration, it becomes i-1 with i = i - 1. Just like in increment, its shorthand form is i--, which is also the commonly used form in the for loops.

Statement

The statement or the body of code is executed when the condition expression returns true.

//initialize var outside the loop
let i = 0;
//use existing var
for (i = 0; i < 3; i++) {
  // to print value of to the console
  console.log(i); 
}
//OUTPUT
0
1
2

In the example above, a simple statement to print the value of i to the console  after each iteration (line 5) is added. This completes our simple for loop example.

Briefly summarizing again,  first value of i is set to 0 (initialization block). Next we set a condition for loop iteration i.e. to run until i is less than 3 (condition block). Finally, value of i was increased by one after each iteration (increment block). The statement block prints value of i to the console (statement block) as shown in the output (lines: 9-11).

Optional ‘for’ Expressions

All the three expressions of the for statement loop are optional.

1. Initialization block can be optional
The initialization expression in our for loop example can be omitted by initializing the var outside the loop (line 2).

//initialize var outside the loop
let i = 0;
//initialize loop with existing var
for (; i < 3; i++) {
  // to print value of to the console
  console.log(i); // => 0, 1, 2
}

Take a note that even though the var i initialization block may not be required in a for loop, a semicolon ; is required (line 2).

2. Condition block can be optional
Like in the initialization block, the condition block is also optional and can be omitted from the for loop as shown below.

//initialize var outside the loop
let i = 0;
//omit initialization & condition
for (; ; i++) {
 // must include break statement
 if (i > 2) { //condition for break
    break; // must be included
 }
  // to print value of to the console
  console.log(i); //=> 0, 1, 2
}

Using the same previous example, the condition block is removed from our for loop example (line 4). But the loop to work, if statement MUST be combined with break statement to reverse the condition ( i > 2) of for loop – to terminate loop iteration if i is greater than 2 (a reverse of true condition).

Warning: The conditional statement MUST be followed by the break statement, otherwise the loop runs forever like in an infinite loop and crashing the browser.

3. Initialization block can be optional
Just like in initialization and condition blocks, the incremental block can also be removed but the loop to work, it should be added at the end of the for loop (line 11).

//initialize var outside the loop
let i = 0;
//omit all expression
for (; ; ) {
 // must include break statement
 if (i > 2) { //break condition
    break; // MUST be included
 }
  // to print value of to the console
  console.log(i); //=> 0, 1, 2
  i++;
}

In the example above, the increment expression is removed from the for loop (line 4) but both the semicolon ( ; ; ) must be included to execute the loop. Just like in the condition block break statement MUST be included so that the condition expresion for break statement returns true at some point.

The ‘for..in’ Statement

An object contains enumerable property where for..in is used to iterate over enumerable property of an object. In a previous learning-post JavaScript Objects – The Basics, use of for..in iteration in an object was  discussed briefly. Enumerable properties show up in for…in loops (once for each property) unless the property’s name is Symbol. A more detail discussion on enumeration is covered in a separate learning-note post – Understanding Enumerable Properties in JavaScript.

Basic Syntax
//basic syntax
for (variable in object) { 
   statement;
}

The for..in syntax takes following two expressions:

  • variable: A different property name is assigned to variable on each iteration.
  • object: Object whose non-Symbol enumerable properties are iterated.
Iterating Over Objects

Using the for..in statement, key and values of an object can be iterated in most straightforward way. A very basic use case example of for..in loop shown below iterates over the properties of an object (keys & values).

//initialize myCar object
let myCar = { make: 'Toyota', model: 'Corolla', year: '2017'
};

//iterate keys with for..in 
for (let key in myCar) { 
   console.log(key); // print object keys
 }
//OUTPUT
make
model
year

//iterate keys with for..in
for (let value in myCar) {
  console.log(myCar[value]); // print object values
}
//OUTPUT
Toyota 
Corolla 
2017

//iterate keys with for..in
for (let key in myCar) {
  //print object keys & values
  console.log(`${key} : ${myCar[key]}`);
}
//OUTPUT
make : Toyota 
model : Corolla 
year : 2017

In the example above, a simple myCar object is created with three name:value pairs (line 2). Using for..in iteration (lines 6) keys (name) of object items can be accessed (lines: 10-12).

Likewise, values of each item can be accessed as the index value of the myCar object (lines: 19-21). Both the key and values of myCar object can be accessed to the console (lines: 29-31).

Iterating Over Arrays

In an array, the key for value are numerical indexes. Just like in an object, these indexes are enumerable properties and thus for..in statement can be used to iterate over arrays.

//initiize myArray
let myArray = [20, 25, 30];
//iterating over with for..in
for (const x in myArray) {
  console.log(myArray[x]);
}
//OUTPUT
20
25
30

Alert. It is a general practice not to use for..in statement to iterate over arrays.

Iterating Over String

Since each character in a string has an index, which are enumerable properties too, and can be iterated using the for..in statement, as shown below:

//initializing myString
let myString = "TOYOTA";
//Iterating over with for..in
for (const x in myString) {
  console.log(myString[x]);
}
//OUTPUT
T
O
Y
O
T
A

Alert. It is a general practice not to use for..in statement to iterate over strings.

The ‘for..of’ Statement

The for..in statement method described in previous section is useful for iterating over object properties. The ES6 introduced for..of statement is used to iterate over strings and arrays.

To quote from the MDN Documentation: “The for...of statement creates a loop Iterating over iterable objects(including ArrayMap, Set, arguments object and so on), invoking a custom iteration hook with statements to be executed for the value of each distinct property“.

The for..of statement is a newer method and was introduced in ECMAScript 6 (ES6) to iterate over “iterable collections“. This is commonly used to iterate over objects like Arrays, Strings, Sets, Maps.

Basic Syntax
//basic syntax
for (variable of iterable) {
  statement;
}

The for..of syntax takes following two expressions:

  • variable: On each iteration a value of a different property is assigned to variable.
  • iterable: Object whose iterable properties are iterated.
Iterating over an Array

In the following example (adopted from the MDN Documentation) the for..of statement is used to iterate over an array because arrays are iterable.

//initializing myArray
let myArray = [20, 25, 30];
//Iterating over for..of
for (let x of myArray) { //using let var
  x += 1; // increase value of x by 1
  console.log(x);
}
//OUTPUT
21
26
31

The let variable (line 4) used in the above example can be replaced with const variable (as shown below, line 15), if the variable is NOT re-assign within the block.

//Initializing myArray
let myArray = [20, 25, 30];
//iterating over with for..of
for (const x of myArray) { //using a const var
  console.log(x);
}
//OUTPUT
20
25
30
Iterating Over a String

The for..of statement is more reliable to iterate over a string, than the for..in statement used in previous section.

//initializing myString
let myString = "TOYOTA";
//iterating over a string with for..of
for (const x of myString) {
  console.log(x);
}
//OUTPUT
T
O
Y
O
T
A

As described in for..in section, each character in a string has an index, which are enumerable. The for..of statement is more reliable method to iterate string object.

Iterating Over Map

Iterating Maps with for..of was discussed previously in a separate post and the same example is revisited below.

Iteration of maps elements with for..of loop goes for each elements in the insertion order and returns an array of [key, value] pair.

//initialize myCar set and add elements
let myCar = new Map([[0, 'Toyota'], [1, 'Honda'], [2, 'Ford']]);

// iterate to print keys only
for (let key of myCar.keys()) {
  console.log(key);
}
//OUTPUT
0
1
2

//iterate values only
for (let value of myCar.values()) {
  console.log(value);
}
//OUTPUT
Toyota
Honda
Ford

//iterate both keys & value
for (let [key, value] of myCar) {
  console.log(key + ' = ' + value);
}
//OUTPUT
0 = Toyota
1 = Honda
2 = Ford

In the example above, for..of statement is used to myCar array to iterate only key values in their order of insertion and print return to the console (lines: 4-11). Similarly, we can iterate only values using for..of statement and print key/value pairs  to the console (lines: 14-20) and to iterate both the keys:values (lines: 23-29).

Iterating Over Set

Iterating Sets object with for..of was briefly discussed previously in a separate post. The for..of statement is more reliable method introduced in ES6 to iterate Sets object.

//initialize Set Objects 
let carSet = new Set(["Toyota", "corolla", 2018, 2018]); 

//iterate Set elements with for..of
for (let item of carSet) console.log(item);
//OUTPUT
Toyota
corolla
2018

In the example above, a carSet object is created and assigned with four items (line 2). By using for..of statement to Set object items (line 2), carSet object elements can be printed to the console in their order of insertion (lines 7-9).

Tip: There are additional use case examples of for..of iteration listed in the MDN Documentation including iterable objects, generators, DOM collection, arguments.

Difference Between for..of and for..in

The difference between the for..in statement and the for..of statement discussed above are summarized in the following table(adopted from bitsofcode).

Iteration for..in Loop
for..of loop
Suitable for Enumerable Properties Iterable Collections
Use with Objects? Yes No
Use with Arrays? Yes, but not advised Yes
Use with Strings? Yes, but not advised Yes

The MDN documentation describes difference between a for...of loop and a for...in loop step by step when used with an Array.

Tip: the for-of statement is used for iterating over arrays and the for-in statement is for iterating over the keys of objects.

Wrapping Up

In this learning-note post use of for statement, for..in statement and for..of statement to iterate enumerable objects were discussed with some use case examples. Some high lights of the difference between the for..in and for..of statements were discussed. A more detail discussion on enumeration is covered in a separate learning-note post – Deep Dive into JavaScript Property Descriptors

Related Post: Learning JavaScript While and Do..While Loops

Useful Resources & Links

While preparing this post, I have referred the following references extensively. Visit original link for additional information.