Thursday, June 18, 2020

Four different breeds of For Loop in JavaScript and When to Use Them


I believe every programmer reading this article must be having knowledge about that traditional for loop, and as far as I know, this loop is probably the same in every language out there.

Languages like JavaScript, however, have four different types of for loop available. And they are not precisely the same.
The four different for loops I am talking about is,
  1. The Classical For Loop
  2. for/in loop
  3. for/of loop 
  4. and the fancy one i.e., for each loop


There are differences between all versions, so in this article, I want to cover all four of them and how and when to use what.

The classical For loop

We all know about this one, right?. This for loop has the following syntax
 for (statement 1; statement 2; statement 3) {  
  // code block to be executed  
 }  
Statement 1 is executed (one time) before the execution of the code block.
Statement 2 defines the condition for the execution of the code block.
Statement 3 is executed every time after the code block has been executed.

I'm sure that you must have written this form of code many times. The sample code for this for loop is as follows.
 for (i = 0; i < 5; i++) {  
  console.log(i);  
 }  

Just to tell, you can run this for loop with as many counters you want. The example being,
 for(let a = 0, b = 0; a < 10 && b < 100; a++, b+=10) {  
   console.log(a, b)  
 }  

Now let's see how we can deal with asynchronous code inside the classical for a loop. Yeah, that's one of the use cases of for loop remember this ;).
 const fs = require("fs")  
 async function read(fname) {  
   return new Promise( (resolve, reject) => {  
     fs.readFile(fname, (err, content) => {  
       if(err) return reject(err)  
       resolve(content.toString())  
     })  
   })  
 }  
 (async () => {  
   let files = ['file1.json', 'file2.json']  
   for(let i = 0; i < files.length; i++) {  
     let fcontent = await read(files[i])  
     console.log(fcontent)  
     console.log("-------")  
   }  
 })()  

Note: the for loop in my example is inside an IIFE simply because, as you probably know, the await instruction needs to be inside an async function. Otherwise, Node won't allow it.


The for/in loop

The javascript statement for/in loop loops through the properties of an object.The syntax of the code being,
 for (var in object) {  
  code block to be executed  
 }  

The block of code inside the loop will be executed once for each property.

This loop is used when you're using  your custom object as hash map or directory (a widespread practice)

Note: Do not just the for/in a statement to loop through arrays where index order is important. Use the for statement instead.

The example for the use of for/in statement is
 let myMap {  
  uno: 1,  
  dos: 2,  
  tres: 3  
 }  
 for(let key in myMap) {  
  console.log(key, "=", myMap[key]);  
 }  
 /*  
 uno = 1  
 dos = 2  
 tres = 3  
 */  

Pretty simple, isn't it? But be warned, because let me tell you that everything in javascript is an abject, so you can end up doing for/in where you actually wanted for/of.

Now, let's have a look on for/of

The for/of loop

The JavaScript for/of statement loops through the values of an iterable object with the syntax being
 for (variable of iterable) {  
  // code block to be executed  
 }  

For/of lets you loop over data structures that are iterable such as Arrays, Strings, Maps, NodeLists, and more.

Now, let's have a look at specific examples of for/of the loop.

Looping over an array

 var cars = ['BMW', 'Volvo', 'Mini'];  
 var x;  
 for (x of cars) {  
  document.write(x + "<br >");  
 }  

Looping over a String

 var txt = 'JavaScript';  
 var x;  
 for (x of txt) {  
  document.write(x + "<br >");  
 }  


Now to keep up with the comparison, Let us introduce asynchronous code for both for/of and for/in loops.
 const fs = require("fs")  
 async function read(fname) {  
   return new Promise( (resolve, reject) => {  
     fs.readFile(fname, (err, content) => {  
       if(err) return reject(err)  
       resolve(content.toString())  
     })  
   })  
 }  
 (async () => {  
   let files = ['file2.json', 'file2.json']  
   for(fname of files) {  
     let fcontent = await read(fname)  
     console.log(fcontent)  
     console.log("-------")  
   }  
   for(idx in files) {  
     let fcontent = await read(files[idx])  
     console.log(fcontent)  
     console.log("-------")  
   }  
 })()  
Both loops react precisely in the same way with the await construct, allowing you to write simpler and cleaner code.

The fancy one i.e., For each loop

This one is probably one of my favourites, maybe because I''m a big fan of declarative syntax or a declarative way of writing your code over imperative. No doubts The above versions of the loop work ready well and have their own perfect use cases, they are also very imperative in the sense that we need to write a whole code stating what needs to happen with our data instead of simply writing what we want to happen to it.

Leaving all the debates aside, the forEach method is yet another version of for loop, this one, however, is part of the array object and meant to receive a function.

The working of for each is as simple as each name sounds. forEach() method calls a function once for each element in an array, in order.

The syntax of for loop is as follows.
 array.forEach(function(currentValue, index, arr), thisValue)  
Function - The function to be run for each element in the array. This is a necessary option and must be provided
CurrentValue- It stores the value of the current element. This is also a must option.
Index - This option is the optional one, and it has the array index of the current element.
Arr- The array object the current element belongs to. This one is optional.
ThisValue-  A value to be passed to the function to be used as its "this" value.
If this parameter is empty, the value "undefined" will be passed as its "this" value. This is also an optional one. 

Example, showing the usage of for each method is
 var numbers = [65, 44, 12, 4];  
 numbers.forEach(myFunction)  
 function myFunction(item, index, arr) {  
  arr[index] = item * 10;  
 }  

Continuing our previous example. For the last time, let's show that asynchronous code works with this one also.
 const fs = require("fs")  
 async function read(fname) {  
   return new Promise( (resolve, reject) => {  
     fs.readFile(fname, (err, content) => {  
       if(err) return reject(err)  
       resolve(content.toString())  
     })  
   })  
 }  
 let files = ['file1.json', 'file2.json']  
 files.forEach( async fname => {  
   let fcontent = await read(fname)  
   console.log(fcontent)  
   console.log("-------")  
 })  

Conclusion

Time to look at what we learned. There are four different types of loop available in JavaScript with their usage according to the use-cases. I tried to make comparisons between the four using the asynchronous code. 

That's all I wanted to share about the JavaScript For loops. I hope now you have a clear understanding of them. However, If you liked reading this article or consider this important, then consider bookmarking this.

If there's Anything, I forgot, or you want me to add something? Just let me know by dropping a comment in the comment section.
Previous Post
Next Post

post written by:

Hi, Navjyot Singh is a coder, content maker and a freelance developer who's pursuing an undergraduate Engineering degree in Computer Science. He started out as a web developer but later picked up the mobile as his favourite platform to develop applications. A Writer by day and coder by night is loathed to discuss himself as the third person but can be persuaded to do so from time to time.

0 comments: