Javascript's For Loop Statements

For loops are a very common functionality when it comes to JavaScript and other programming languages. Sitting down to create this article, I thought I’d only be stating the obvious and there would be nothing really to write about… Well, that wasn’t entirely true. It appears that there are a few very significant differences between for…in and for…of loops statements which I wasn’t aware of.

Javascript's For Loop Statements
Contributor Photo - Maria Polewczyk

Maria Polewczyk

JavaScript Developer

The main aim of using loops is to do something repeatedly. If you need to execute a few lines of code five times or display a component several times, this is exactly what you’re looking for!

For statement

Before we dive into newer solutions, let’s examine the for loop statement, which has been with us for quite some time now.

const scrumTeam = ["developer", "designer", "scrum master"]; for (let i = 0; i < scrumTeam.length; i++) { console.log(scrumTeam[i]); }

I guess this one is pretty obvious, but let’s go through the syntax and what happens here briefly.

for ([initialExpression]; [condition]; [incrementExpression]) { statement }

Firstly, I’m creating an array of scrum team roles and then I’m trying to console log all of them. Every basic for loop consists of a few steps:

  1. The initial expression is declared and initialised. This step is not mandatory - it can be omitted and there will be no loop counters,
  2. The condition is checked to determine whether we should execute the block of code inside the loop’s body or not - if true is returned, we proceed and execute,
  3. If it is true, we proceed with executing the programmed statement within the loop’s body. If the condition returned false - the loop terminates. There is also a possibility that there is no condition at all and then the condition is treated as if it was true - the loop is then an infinite one.
  4. The last step is to execute the increment expression - and we go back to step two.

Omitting the initial expression, condition or increment expression doesn’t change the fact that we still need to keep the three-part statement, but we can leave a specific part empty. For example, omitting all expressions leaves us with for(;;), which will create an infinite loop.

I believe there was no magic in here and as a result of the above example, we will see:

developer designer scrum master

That was way too simple, right? So JavaScript has two more for loops, which are worth taking a look at and these are for…in and for…of loops. Let’s see take a look at the difference between them.

For…in statement

First of all, the for…in loop. MDN docs say that “A for…in loop only iterates over enumerable, non-Symbol properties”. What exactly does that mean?

It applies to all objects which have the mentioned properties. These are arrays and strings, which have indexes, as well as objects, which have keys. We cannot use this loop to iterate over any of the primitives, such as Boolean.

The syntax in a for…in loop is following

for (variable in object) { … }

The syntax seems to be pretty easy, so let’s try it on few snippets of code.

The first example presents iterating over an object’s properties:

const kitten = {
  name: "Daisy",
  fur: "black",
  eyes: "green",
  age: "1"
};

for (const feature in kitten) {
  console.log(`kitten's ${feature}: ${kitten[feature]}`);
}

The variable contains a different property name of an object for each iteration. What does it look like for the above example?

During the first iteration, feature is assigned to kitten’s first property which is name. In this snippet of code we’re referring to both the object’s property and its value. Here’s the result of the above code:

kitten's name: Daisy kitten's fur: black kitten's eyes: green kitten's age: 1

You might think that the above example shouldn’t work, as we have const in this statement, but is that really true? This wouldn’t work for a regular for loop, as we cannot reassign a const variable. But aren’t we reassigning it here as well? Apparently we’re not. A new block of scope is created for each iteration, meaning there’s a new index as a brand new variable within a new scope. This way, our constant is never reassigned.

We know that objects have properties, so iterating over them was rather obvious. But what happens when we want to use for…in for an array? Let’s see how it goes.

const cats = [ "Bengal", "Maine Coon", "British Longhair", "Don Sphynx" ]; for (const cat in cats) { console.log(cats[cat]); }

As a result we get a list of cats’ breeds, because for arrays, the element’s index is the enumerable property we’re iterating over.

Unfortunately, there is a downside to this for loop - it is not guaranteed that the indexes will be returned in any particular order. It is true that this issue only appears in older browsers, but as for arrays, the order of the access is important and it is recommended not to use for…in but for…of instead.

Similarly, strings can also be iterated over as each character has an index.

const string = "boldare"; for (const index in string) { console.log(string[index].toUpperCase()); }

We will get this as a result in our console:

B O L D A R E

For…of statement

This solution is a bit younger - it first appeared in ES2015 - and according to MDN docs, Internet Explorer doesn’t support it at all.

The previous loop was iterating over enumerable properties, however this one iterates over iterable collections. These collections can be arrays, maps, sets and few more. If we tried using this kind of loop on an object, we would get a type error saying that the object is not iterable.

The syntax for this one differs a little bit from the for…in loop:

for (variable of iterable) { … }

The simplest example I can think of is iterating over a regular array.

const animals = ["cat", "dog", "elephant"]; for (const animal of animals) { console.log(animal); }

The result of this code is:

cat dog elephant

In the case of for…of, the variable is initialized with the values themselves, so there is no need to access the array’s items. If we iterated over a string, we would also get the characters immediately from a variable within the loop.

In the example below, we can see that it’s also possible to retrieve values immediately from a nested array within one for loop, instead of creating two nested loops.

const nestedArray = [[1, "one"], [2, "two"], [3, "three"]];

for (const [firstValue, secondValue] of nestedArray) {
  console.log(`${firstValue} is: ${secondValue}`);
}

And the result will be the following:

1 is: one 2 is: two 3 is: three

The difference between for…of and for…in

As mentioned in the previous section, the main difference between these two for loops is what they iterate over. There is one more significant difference between these two, as shown in the below example.

const array = []; array[3] = "fourth element"; for (const i in array) { console.log(array[i]); } for (const i of array) { console.log(i); }

As we already know, both loops should log all the elements from the array, but is it really the same? As usual in such cases - the answer is no…

The first loop will only return one value:

fourth element

The for…of loop however, will show a slightly different result:

undefined undefined undefined fourth element

The reason why it’s being logged in such way is because for…in logs only properties with a value, while for…of logs every element from the array. The regular for loop would log the array’s elements just the same as for…of does.

Another difference is when we add additional properties to an array’s prototype and then we’re trying to loop over an array. Let’s take a look at an example:

Array.prototype.four = 4; const digits = [1, 2, 3]; for (const index in digits) { console.log(digits[index]); } for (const digit of digits) { console.log(digit); }

The result for the for…in loop will be:

1 2 3 4

For the for…of, however it will not have the last element:

1 2 3

They differ because the for…in loop iterates over all enumerable properties, which also includes those added to the array’s prototype.

You might be also interested in the article:

Marble.js – new open source framework for JavaScript

Marble.js – new open source framework for JavaScript

Other JavaScript loops

For loops are not the only type provided in JavaScript, so I’d like to present a number of other loops very briefly. In most cases they can be used as alternatives as they all repeatedly execute the given code, but there are various situations in one is prefered over the others. They also differ from each other according to the start and end points of the loop.

While statement

The syntax for a while statement goes like this:

while (condition) { statement }

So, basically what happens here is that the statement is being executed as long as the condition is fulfilled. What is more, the condition is being checked before code execution begins. Let’s dive into some code…

let sum = 0; while (sum < 13) { sum += 4; console.log(sum); }

The result will be:

4 8 12 16

When the sum is no longer less than 13, the condition will return false, therefore the execution stops and control is passed to further code.

A special case of while statement is an infinite loop. The simplest is:

while (true) { console.log('JavaScript'); }

Do…while statement

This one differs from the previous statement. Here, the code will execute and then the condition is checked. So the syntax is also a little different:

do { statement } while (condition)

Does it make any difference when the condition is tested? Yes, it does. Even if the condition was false from the beginning, the code will always execute once just before the analysis.

do { console.log('JavaScript'); } while (false)

And as we expect, it will return a single JavaScript.

Conclusion

We have covered most of the use cases and tricky behaviors of for loops in JavaScript. The for…in loop it is not recommended for arrays, but it applies to enumerable properties. The for…of loop however, is perfectly suited for iterable collections, like the above-mentioned arrays and it’s impossible to use on an object.

I hope that reading this article helped you broaden your knowledge and I strongly encourage you to experiment some more with these loops!

Contact:

Let's talk about
your business