Multiple Ways To Create Loops In JavaScript

Photo by Ferenc Almasi on Unsplash

Loops are used in JavaScript to perform repeated task(s) based on conditions. Conditions typically return true or false when analysed. A loop will usually continue running until the defined condition returns false.

There are different kinds of loops supported by JavaScript, which typically are:

  1. for — loops through a block of code a number of times.
  2. for/in — loops through the properties of an object.
  3. for/of — loops through the values of an iterable object.
  4. while — loops through a block of code while a specified condition is true.
  5. do/while — loops through a block of code while a specified condition is true.

Although they all do similar things, some loops can be the better choice in specific situations. That depends on your use cases.

I will also discuss 2 extra looping methods that are typically used as well which are:

  1. forEach()
  2. map()

P.S. The variables are declared here with var keyword as it is the most generally well known and the first thing learned usually. You can substitute it with let or const where it fits.

Let’s begin the explanation!


1. For Loop

Syntax:

for ([initialization]); [condition]; [final-expression]) {
// statement (code block to be executed)
}

This loop consists of 3 expressions and a statement:

  1. Initialization (executed (one time) before the execution of the code block) — Initialize the loop variable with a starting value. This expression is commonly used to define counters and also variables. Here is when you usually define the starting point of the loop, loop variable. For example, you can use the initialize expression to define a counter with value of 0. This means that the loop will start at “0”. You can use any name for this counter.
    When you want to define some variables, along with the counter, you separate them, and also the counter, with commas: let counter = 0, let myVar = 5. You can use as many variables as you want.
    Variables created here are scoped to the loop. Once the loop has finished its execution they are destroyed.
  2. Condition (defines the condition for executing the code block) — Expression that is checked prior to the execution of every iteration. If omitted, this expression evaluates to true. If it evaluates to true, the loop’s statement is executed. If it evaluates to false, the loop stops.
  3. Final expression (executed (every time) after the code block has been executed) — Expression that is run after every iteration. Usually used to increment a counter. But it can be used to decrement a counter too.
  4. Statement — code to be repeated in the loop

Any of the 3 expressions can be omitted. You could also create a For loop with an empty head, without any of the expressions. One thing to remember is that when you decide to omit some expression, you still need to add the semicolons. In other words, For loop will always contain two semicolons, regardless of how many expressions there are. For loops are commonly used to count a certain number of iterations to repeat a statement. Use a break statement to exit the loop before the condition expression evaluates to false.

Example of For loop with increment condition:

/*
* A simple for loop to iterate up to 5
* The “i” is the counter, starting point of the loop. Starts from 0 in this case.
* The “i < 6” condition says that the loop will run as long as the counter’s value is smaller than 6.
* The “i++” says that the counter will be incremented by 1 at the end of each iteration
*/
for (var i = 0; i < 6; i++) {
  // log the current value of “i” counter
  console.log(i);
}
// Output:
0
1
2
3
4
5

Example of For loop with decrement condition:

/*
* A simple for loop to iterate down to 0
* The “j” is the counter, starting point of the loop. Starts from 5 in this case.
* The “j >= 0” condition says that the loop will run as long as the counter’s value is bigger than 0.
* The “j--” says that the counter will be decremented by 1 at the end of each iteration
*/
for (var j = 5; j >= 0; j--) {
  // log the current value of “j” counter
  console.log(j);
}
// Output:
5
4
3
2
1
0

Example of For loop without initialization expression:

/*
* A simple for loop with no initialization expression
* Semicolon is still included.
*/
var k = 0;
for (; k < 3; k++) {
  // log the current value of “k” counter
  console.log(k);
}
// Output:
0
1
2

Example of For loop without condition expression:

/*
* A simple for loop with no condition expression
* Semicolon is still included.
*/
for (var l = 3;; l--) {
  // log the current value of “l” counter
  console.log(l);
  
  // Terminate the loop when the counter reaches 0
  // If you don’t terminate the loop without condition
  // or with condition that never happens
  // it will create an infinite loop, i.e. the loop will run forever
  if(l === 0) break;
}
// Output:
3
2
1
0

Example of For loop without increment/decrement expression:

/*
* A simple for loop with no increment/decrement expression
* Semicolon is still included.
* This will create an infinite loop because the counter is not updated and will forever run the condition true.
*/
for (var m = 0; m < 9999;) {
  // log the current value of “m” counter
  console.log(m);
  // Include m++ here to increase the counter at least
}
// Output:
0
0
0
0
.
.
.
… infinite loop (always 0)

Common Pitfall(s)

– Exceeding the bound of an array

When indexing over an array many times, it is easy to exceed the bound of the array (e.g. try to reference the 4th element of a 3-element array).

// This will cause an error.
// The bound of the array will be exceeded.
var arr = [ 1, 2, 3 ];
for (var i = 0; i <= arr.length; i++) {
  console.log(arr[i]);
}
// output:
1
2
3
undefined

Fixesi < arr.length or i <= arr.length-1 or break out of the loop before condition expression is false like break before it reaches the 4th element using the break statement.


2. For…in Loop

This loop is usually used for objects.

This iterates over the enumerable properties of an object, in arbitrary order.

It starts with for keyword, followed by parenthesis containing a variable, in keyword and name of an object you want to iterate over. The loop continues until all properties of the object are through.

Syntax:

for (variable in object) {
  // statement(s)
}

Example:

var user = {
  firstName: ‘Mark’,
  lastName: ‘Zuck’,
  age: 42
}
for (var property in user) {
  console.log(`Key: ${property}, Value: ${user[property]}.`);
}
// Output:
Key: firstName, Value: Mark.
Key: lastName, Value: Zuck.
Key: age, Value: 42.

If it loops through an array, the variable here is the index. So in order to get the value, use object[variable].

Example:

var alp = [‘a’,’b’,’c’];
for (var property in alp) {
  console.log(`Key: ${property}, Value: ${alp[property]}.`);
}
// Output:
Key: 0, Value: a.
Key: 1, Value: b.
Key: 2, Value: c.

3. For…of Loop

This works similarly like the For…in Loop.

This creates a loop iterating over iterable objects (including Arrays, Maps, Sets, Strings and so on), invoking a custom iteration hook with statements to be executed for the value of each distinct property.

Note that “iterable object” is not the same as “object”. Objects are objects, “things” with properties, key-value pairs. Iterable objects are Arrays, Maps, Sets, NodeLists, Strings, etc.

For the variable, during each iteration, one item from that array (e.g.) will be assigned to the variable you specify before the ‘of’ keyword. Same as For…in Loop, it will continue looping until there are no items left to be iterated.

Syntax:

for (variable of object) {
  // Statement(s)
}

Example with Array:

let arr = [ "mark", "zuck", "bob" ];
for (var i of arr) {
  console.log(i);
}
// Output:
mark
zuck
bob

Example with Map:

var m = new Map();
m.set(1, "black");
m.set(2, "red");
for (var n of m) {
  console.log(n);
}
// Output:
[1,”black”]
[2,”red”]

Example with Map another way:

var m = new Map();
m.set(1, "black");
m.set(2, "red");
for (var [key, value] of m) {
  console.log(key);
  console.log(value);
}
// Output:
1
black
2
red

Example with Set:

var s = new Set();
s.add(1);
s.add("red");
for (var n of s) {
  console.log(n);
}
// Output:
1
red

Example with String:

var str = ‘Mark’;
for (var s of str) {
  console.log(s);
}
// Output:
M
a
r
k

4. While Loop

This loop might be easier to remember as the syntax is seemingly much easier in a glance. This might be especially true when one compares it with the original For Loop.

This loop starts by evaluating the condition. If the condition is true, the statement(s) is/are executed. Otherwise, the statement(s) is/are not executed.

Syntax:

while (condition)
{
  statement(s);
}
  • statement(s): Executable code as long as the condition evaluates to true.
  • condition: A boolean expression which is evaluated before each pass through the loop. If this condition evaluates to true, statement(s) is/are executed. When it evaluates to false, execution continues with the statement after the while loop.

Example:

/*
* Condition: i < 10
* Counter: i starting from 1
*/
var i = 1;
while (i < 10) {
  console.log(i);
  // Needs to increment the counter so that it will meet the condition and terminate
  // Otherwise, infinite loop will be created
  i++; // i=i+1 same thing
}
// Output:
1
2
3
4
5
6
7
8
9

While loops will run over and over again as long as the condition is true. Running without an end condition will cause it to run an infinite loop.

For example, if the above does not have the limit 10, it will continue running as the variable i is always evaluated as true as it has legit value.

Another one would be when there is no increment to the variable i. For this case, the value of i is always less than 10, hence it creates an infinite loop.


5. Do…While Loop

This loop will execute the code block once, before checking if the condition is true, then it will repeat the loop as long as the condition is true.

It is similar to While Loop, except it runs one time first before checking condition for the next iteration. This means that the code that follows after the do is evaluated before the while condition is evaluated. In other words, the code will always run at least once, even if the condition evaluates to false for the while loop.

Syntax:

do {
  Statement(s);
} while ([condition]);
  • statement(s): Executable code at least once before the condition or boolean expression is evaluated and is re-executed each time the condition evaluates to true.
  • condition: A boolean expression. If it evaluates to true, the statement is executed again. Otherwise, the loop ends.

Example:

var i = 0;
do {
  i = i + 1;
  console.log(i);
} while (i < 5);
// Output:
1
2
3
4
5

Don’t forget to increase the variable used in the condition or it risks having an infinite loop.


6. forEach()

This is an array’s method that uses a callback function to include any custom logic to the iteration. In other words, it will execute the provided callback function once for each array element.

Syntax:

array.forEach(callbackFunc(currentValue [, index [, array]])[, thisArg]);

callbackFunc refers to the callback function that takes up to 3 arguments:

  1. currentValue — the data/value of the current element
  2. index (optional) — the array index of the current element
  3. array (optional) — the entire array object

thisArg (optional) — Value to be passed to the callback function which will be used as its this value.

You cannot use break to get out of the loop.

Example:

var totalCost = 0;
var items = [
  {item: ‘one’, cost: 12},
  {item: ‘two’, cost: 14},
  {item: ‘three’, cost: 16}
];
items.forEach(function(itemPair, index, theArray){
  this.totalCost += itemPair.cost;
}, this);
console.log(totalCost);
// If “this” wasn’t included in the argument, this.totalAge will still be 0
// Output:
42

7. map()

At first glance, map() method looks very similar to forEach() method as it will also execute the provided callback function once for each array element. The only major difference is that map() method will create and return a new set of arrays based on the result of the callback function.

According to the documentation, one should use forEach() or For…of Loop instead of map() method if you’re not using the newly created array it returns and/or you’re not returning a value in the callback function. Else it will be considered as an anti-pattern.

Syntax:

var newArray = array.map(callbackFunc(currentValue [, index [, array]]){
  // Return element for the newArray
}[, thisArg]);

callbackFunc — the callback function that takes up to 3 arguments:

  1. currentValue — the data/value of the current element
  2. index(optional) — the array index of current element
  3. array(optional) — the entire array object

thisArg(optional) — value to be passed to the callback function which will be used as its ‘this’ value.

return — a new set of array based on the return result of the callback function.

You cannot break out of a map() method.

Example:

var items = [
  {item: ‘one’, cost: 12},
  {item: ‘two’, cost: 14},
  {item: ‘three’, cost: 16}
];
var newArray = items.map(function(item, index, itemsArr){
  var newItem = {
    ‘item’: item.item,
    ‘cost’: item.cost * 2
  };
  return newItem;
});
newArray.forEach(function(newItem, index, newItemsArr){
  console.log(`Cost ${newItem.item}: ${newItem.cost}`);
});
// Output:
Cost one: 24
Cost two: 28
Cost three: 32

Extra: Infinite Loop

Sometimes, infinite loops might happen when one is careless about it. To put it simply, infinite loop is a loop that never ends and might freeze your computer or crash your browser as the potential result.

This happens when the condition used in a loop always evaluates to true and never to false. The only way out of this is to ensure your loop has an end to it.

This situation often happens to “while” loops especially. The “while” loop makes it easy to forget setting an eventual false condition. So, pay attention to the code you are writing and remember to watch for typos. Otherwise, lower the chance by using other loops accordingly.


That’s all for the loops for now. I hope this article is of help to you. If you think that this article is helpful and it can be of help to other people, please share for them to read as well. Your thoughts and comments are also welcome!

Thank you for reading!