6 Ways to Loop an Array with JavaScript

Are you looking to improve your knowledge of arrays and looping in JavaScript? Look no further! In this article, we will explore six different methods for looping over an array in JavaScript. Whether you are a beginner or an experienced developer, these techniques will come in handy in your day-to-day coding.

Loop an Array with JavaScript

In general, the best way to loop through an array in JavaScript depends on the specific needs of your program. If you need to access the array elements using their indices, you might want to use a for...in or a for loop.

If you want to perform a specific operation on each array element without worrying about their indices, you might want to use the forEach() or map() method.

If you want a more modern and concise way, you might want to use a for...of loop.

This article will address each of these methods and a few others. Use the navigation below to jump to the specific explanation for each method.


for loop

A for loop is a type of loop that is commonly used to repeat a specific set of instructions a predetermined number of times. It is called a for loop because it is typically used to perform an action for a specific number of times, or for each element in a collection, such as an array.

When writing a for loop, the code follows this structure:

for (initialization; condition; ending operation) {
  // loop body
}
  • Initialization - this part specifies the initial value of the loop counter.
  • Condition - this is where the condition on which the loop is executed is set. If the condition is false, the loop will stop, and the loop body will not be executed.
  • Ending operation - this part defines the expression that will be executed after the loop body is executed. Usually, this contains an expression to change the counter.

Here is an example of how you might use a for loop to loop through an array and log each element to the console:

const fruits = ['apple', 'banana', 'pear'];

for (let i = 0; i < fruits.length; i++) {
  console.log(fruits[i]);
}

In the example above, the for loop continues to iterate over the elements in the fruits array until the value of i is equal to the length of the array. At this point, the loop terminates, and execution continues to the next statement after the loop.

Also, if necessary, you can interrupt the loop with the break operator, and likewise - resume the loop using the continue operator. Here's an example:

for (let i = 0; i < 10; i++) {
  if (i === 5) {
    break;
  }
  console.log(i);
}

When the loop reaches the value 5, the break operator is executed and the loop is terminated. This means that the loop will only run five times and will output the following:

0, 1, 2, 3, 4.

The continue operator, on the other hand, can be used to immediately skip the remaining code in the body of a for loop and continue to the next iteration of the loop:

for (let i = 0; i < 10; i++) {
  if (i % 2 === 0) {
    continue;
  }
  console.log(i);
}

In this example, when the loop reaches a value that is divisible by 2 (i.e. an even number), the continue operator is executed and the loop skips the remaining code in the body and continues to the next iteration.

This means that the loop will only output the odd numbers between 0 and 10, like this:

1
3
5
7
9

for..in loop

A for...in loop is a control flow statement that allows you to iterate over the properties of an object. In contrast to a for loop, which can only be used to iterate over the elements of an array, a for...in loop can be used to iterate over the properties of any object.

for…in allows you to loop through enumerated object properties, including properties from the prototype. Enumerated properties are properties that the developer adds to an object. Built-in properties, such as length in an array, are not looped in the for…in loop.

Here is an example of how you might use a for...in loop:

const person = {
  name: 'John Doe',
  age: 32,
  gender: 'male',
};

for (const property in person) {
  console.log(property);
}

After the loop body is executed for a given property, the loop continues to the next property in the object, and the process repeats. The loop continues to iterate over the object's properties until it has visited all the properties. At this point, the loop terminates, and execution continues to the next statement after the loop.

You can use a for...in loop to perform any action on each property of an object. For example, you can use it to calculate the sum of all the values of a certain property in an object, or to create a new object with a subset of the original object's properties.

Like so:

const original = {
  make: "Toyota",
  model: "Corolla",
  year: 2020,
  color: "blue"
};

const subset = {};

for (const property in original) {
  if (property === "make" || property === "model") {
    subset[property] = original[property];
  }
}

console.log(subset);

At the end, the subset object will contain the make and model properties from the original object, and will look like this:

{
  make: "Toyota",
  model: "Corolla"
}
☰ What are enumerated properties?

In JavaScript, an object's properties can be enumerated using the for...in loop. This loop will iterate over all the enumerable properties of an object, including those that may have been inherited from the object's prototype.

const car = {
  make: "Ford",
  model: "Mustang",
  year: 2021
};

for (const property in car) {
  console.log(`${property}: ${car[property]}`);
}


// output

make: Ford
model: Mustang
year: 2021

By default, all properties of an object are enumerable, unless they have been explicitly marked as non-enumerable using the Object.defineProperty() method.

Object.defineProperty(car, "make", {
  enumerable: false
});

In this example, the make property of the car object has been marked as non-enumerable. This means that it will not be included when the object's properties are enumerated using a for...in loop.


for..of loop

Unlike the traditional for loop, the for...of loop automatically retrieves the value of each element in the iterable object. This means you don't have to worry about managing the loop index or accessing the array elements, which can make the code cleaner and easier to read.

Here's an example of using a for...of loop:

const numbers = [1, 2, 3, 4, 5];

for (const number of numbers) {
  console.log(number);
}

On each iteration, the loop logs the current element to the console.

The for...of loop is similar to the for...in loop, but there are some important differences between the two. The for...in loop iterates over the properties of an object, while the for...of loop iterates over the elements of an iterable object.

Here's an example of using a for...of loop to iterate over the characters of a string:

const message = "Hello, world!";

for (const character of message) {
  console.log(character);
}

You can use this loop to perform any action on each value of an iterable object.

In this example, we use the for...of loop to iterate over the keys and values of an object:

const user = {
  firstName: "John",
  lastName: "Doe",
  age: 35
};

for (const [key, value] of Object.entries(user)) {
  console.log(`${key}: ${value}`);
}

On each iteration, the loop logs the current key and value to the console.

☰ When was for..of loop released?

The for...of loop is a relatively new feature in JavaScript and was introduced as part of the ECMAScript 6 (ES6) specification in 2015.

It's not supported in older versions of the language, but most modern browsers and other JavaScript environments support it, so it's widely available for use in real-world projects.


filter()

The .filter() array method allows you to get a new array by filtering the elements with the passed callback function. The callback function will be called for each element of the array, and the result of the function will decide whether to include that element in the new array or not.

Here's an example of how you might use the filter() method to create a new array that only contains numbers greater than 10:

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

const greaterThanTen = arr.filter(num => num > 10);

// greaterThanTen is now [11, 12, 13, 14, 15]

It's worth noting that the filter() method does not modify the original array. It creates a new array that contains only the elements that pass the condition specified in the callback function.

This is different from other array methods like map() and forEach() which do modify the original array. We'll talk about those shortly.

Also, in JavaScript, variables can be dynamically typed, meaning that the type of a variable can change at runtime. This means that the type of a given value that is passed to the callback function in the filter() method can potentially change during the execution of the program.

For example, consider the following code:

const arr = [1, 2, "3", 4, "5", 6, 7, 8, 9, 10];

const onlyNumbers = arr.filter(val => typeof val === "number");

// onlyNumbers is now [1, 2, 4, 6, 7, 8, 9, 10]

In the code above, the arr array contains both numbers and strings. When the filter() method is called on arr, the callback function checks if the current element (val) is a number using the typeof operator. If an element is a number, it is included in the new array that is returned by filter().

However, because JavaScript is dynamically typed, the type of the elements in the arr array can potentially change at runtime. This means that the elements that are considered "numbers" by the filter() method can change depending on the types of the elements in the arr array.

For instance, if the arr array were to be modified to contain only strings, the onlyNumbers array would be empty because the filter() method would only include elements in the new array if they are of type number.

arr = ["foo", "bar", "baz"];

onlyNumbers = arr.filter(val => typeof val === "number");

// onlyNumbers is now []

In this way, the behavior of the filter() method can be affected by dynamic typing in JavaScript. It is important to consider this when using the filter() method and to ensure that the callback function is able to handle elements of different types.


forEach()

The forEach() array method allows you to apply a callback function to all elements of the array - it can be used instead of the classic for loop if only because forEach() looks more readable and understandable.

Also, take note that this method does not return a new array like some other array methods (e.g. map() and filter()). Instead, it simply executes the provided callback function for each element in the array.

This means that the forEach() method is often used for its side effects (e.g. logging to the console or modifying the elements in the array) rather than for its return value.

Let's create a new array of objects from an existing array of objects:

const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Carol" }
];
const newUsers = [];

users.forEach(user => {
  if (user.id % 2 === 0) {
    newUsers.push({ id: user.id, name: user.name });
  }
});

// newUsers is now [{ id: 2, name: "Bob" }]

This callback function is executed once for each element in the users array, resulting in a new array of objects being created that only contains elements where the id property is even.

It is important to know what parameters are accepted by the callback.

There are three of them in total:

  • item - element of the array in the current iteration;
  • index - index of the current item;
  • arr - the array itself, which we are going through.
.forEach((item, index, arr) => {
   ...
})

Although JavaScript already has the ability to do this using the for loop, the forEach() method is a great alternative with a number of advantages:

  • Using the forEach() method is a declarative way to denote our operation. In terms of code readability, it's more close to natural language and more concise.
  • It allows us to conveniently retrieve an element in the current iteration without referring to the array by index every time.

However, at the same time we also get a few drawbacks:

  • With forEach() - return, break and continue will not work, and therefore we cannot interrupt or skip an iteration in any way. So if we need to use any of these operators to solve a problem, we will have to use the usual for loop.
  • forEach() handles the array elements in direct order; we can't go through the array from the end.

map()

The map() method allows you to transform one array into another using a callback function. The passed function will be called for each element of the array in order. A new array will be assembled from the results of the function call.

Imagine that you have an array of strings that represent the names of your friends. You want to create a new array that contains the length of each of your friend's names. Here is how you could use the map() method to accomplish this:

const friends = ["Alice", "Bob", "Charlie", "Dana", "Eve"];
const nameLengths = friends.map(friend => friend.length);

You could then use the nameLengths array to, for example, find the longest or shortest name among your friends.

const longestName = Math.max(...nameLengths);
const shortestName = Math.min(...nameLengths);

One benefit of using the map() method is that it is a concise and easy-to-read way to loop through an array and apply a specific function to each element in the array. It is often preferred over a for loop because it is less verbose and easier to understand at a glance.

Another benefit of using the map() method is that it creates a new array with the transformed values, rather than modifying the original array.

This allows us to avoid mutating the original array, which can be important for maintaining the integrity of the data and avoiding unintended side effects.

☰ map() and modern frameworks

When working with React or a similar library, map() is the most common way to transform an array of data into components that will end up on a page:

import React from 'react';

const App = () => {
  const data = [1, 2, 3, 4, 5];

  return (
    <ul>
      {data
        .filter(datum => datum % 2 === 0)
        .map(datum => (
          <li key={datum}>{datum}</li>
        ))}
    </ul>
  );
};

What about while?

A while loop lets you to repeat a block of code while a certain condition is true.

However, using the while loop is generally advised against because it requires you to manually keep track of the loop counter and terminate the loop when the end of the array is reached. This can make the code more complex and difficult to read, especially for larger arrays or more complex operations.

It can also cause problems such as creating infinite loops:

const users = [  {    firstName: "John",    lastName: "Doe",    email: "johndoe@example.com"  },  {    firstName: "Jane",    lastName: "Doe",    email: "janedoe@example.com"  },  {    firstName: "Bob",    lastName: "Smith",    email: "bobsmith@example.com"  }];

let i = 0;
while (i < users.length) {
  const user = users[i];
  sendNotificationEmail(user.email);
}

In this code, the while loop is used to iterate over the elements of the users array and send notification emails to each user. However, the i++ statement is inside the body of the loop, and not part of the termination condition. This means that the value of i will never be incremented, and the loop will run indefinitely, causing the program to crash or hang.