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
orconst
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 returnsfalse
, statements are not executed and loop terminates. If the conditions are omitted, it is evaluated astrue
. - 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 Array
, Map
, 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.
- Loop & Iteration | MDN Documentation
- Understanding for loops | Zell Liew
- for..in versus for..of Loops | bitsofcode