If you're tired of writing repetitive code to iterate over arrays and objects, it’s time to discover the higher-order loops.
Higher-order loops provide an easy and powerful way to work with data collections, making your code clearer, shorter, and easier to maintain.
Unlike traditional loops, higher-order loops are methods that take a callback function and apply it to each element in a collection.
Yes, this is a defining feature of higher-order loops: they accept a function as an argument to process each element in a collection.
So Instead of using traditional for or while loops, we will use high-order loops use functions like map, filter, reduce, and others to handle looping in a more abstract and often more readable way.
Additionally, for...of and for...in loops provide a more straightforward syntax for iterating over values and properties without the need for a callback function.


For Of Loop
The for...of loop is a modern iteration statement in JavaScript that simplifies looping over iterable objects such as arrays, strings, maps, sets, and other objects that implement the iterable protocol. It allows you to traverse all the elements of an iterable without having to worry about the index or the length property.
The for...of loop is a modern iteration statement in JavaScript that simplifies looping over iterable objects such as arrays, strings, maps, sets, and other objects that implement the iterable protocol. It allows you to traverse all the elements of an iterable without having to worry about the index or the length property.
Syntax
for (variable of iterable) {
// statement
}- variable: A variable that will be assigned the value of each iterated element.
- iterable: An object that has iterable properties, like an array, string, set, map, etc.
The for...of loop is particularly useful when you need to iterate over all elements of an array, string, or any other iterable, without the need to access the index or perform specific operations based on the index.
Iterating Over Different Data Types
Iterating Over an Array
const numbers = [1, 2, 3, 4, 5];
for (const number of numbers) {
console.log(number);
}
// Output: 1 2 3 4 5This code snippet creates an array called numbers containing the values 1, 2, 3, 4, and 5. It then uses a for...of loop to iterate over each element in the numbers array. During each iteration, the current element is assigned to the variablenumber, and then the console.log() function is used to output the value of number to the console. This loop will output each number in the numbers array on a separate line.
Iterating Over a String
for (const char of message) {
console.log(char);
}
// Output: H e l l oIterating Over a Map
Maps are collections of key-value pairs where each key is unique. When iterating over a map, you use the for...of loop along with destructuring to access each key-value pair.
const userRoles = new Map();
userRoles.set("John", "Admin");
userRoles.set("Jane", "Editor");
userRoles.set("Doe", "Viewer");
for (const [user, role] of userRoles) {
console.log(`${user}: ${role}`);
}
// Output: John: Admin
// Jane: Editor
// Doe: ViewerMap Characteristics:
- Unique Keys: Each key in a map must be unique. Adding a key that already exists will overwrite the previous value.
- Maintained Order: Maps maintain the insertion order of the key-value pairs. The first element inserted will be the first one iterated over, and so on.
Iterating Over a Set
A Set in JavaScript is a collection of unique values. It can hold any type of values, whether primitive or object references.
Characteristics of a Set:
- Unique Values: Each value must be unique; duplicates are not allowed.
- Order of Insertion: Maintains the order of element insertion.
- Iterable: Sets are iterable, allowing you to use loops such as
for...of.
const uniqueNumbers = new Set([1, 2, 3, 4, 5]);
for (const number of uniqueNumbers) {
console.log(number);
}
// Output: 1 2 3 4 5Using for...of with the arguments Object
The arguments object is an array-like object accessible inside functions that contain the values of the arguments passed to that function.
Note that it is not a real array, so array methods like forEach or map cannot be directly used on it without converting it to a real array first. Each argument can be accessed using a zero-based index.
function sum() {
let total = 0;
for (const num of arguments) {
total += num;
}
return total;
}
console.log(sum(1, 2, 3, 4)); // Output: 10This code snippet defines a function called sum that calculates the total sum of all the arguments passed to it. It uses a for...of loop to iterate over the arguments object, which contains all the arguments passed to the sum function.
Since the sum function definition does not specify a fixed number of parameters,it can accept a variable number of arguments and it uses the arguments object to access all the arguments passed to the function.
The for...of loop then iterates over these arguments, allowing the function to handle any number of arguments provided when it is called.
Using for...of to iterate on Object
The for...of loop is not directly applicable to plain objects because they are not iterable by default. However, you can still iterate over the properties of an object using alternative methods, such as Object.keys(), Object.values(), or Object.entries(), combined with the for...of loop.
Iterating Over Object Properties Using for...of
- Using
Object.keys(): Iterates over the keys of the object. - Using
Object.values(): Iterates over the values of the object. - Using
Object.entries(): Iterates over the key-value pairs of the object.
Examples
Iterating Over Keys
const user = {
name: "John",
age: 30,
profession: "Developer",
};
for (const key of Object.keys(user)) {
console.log(key);
}
// Output:
// name
// age
// professionIterating Over Values
const user = {
name: "John",
age: 30,
profession: "Developer",
};
for (const value of Object.values(user)) {
console.log(value);
}
// Output:
// John
// 30
// DeveloperIterating Over Entries
const user = {
name: "John",
age: 30,
profession: "Developer",
};
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}
// Output:
// name: John
// age: 30
// profession: DeveloperFor IN Loop
The for...in loop in JavaScript is used to iterate over the enumerable properties of an object. This includes properties that are inherited through the prototype chain unless those properties are non-enumerable.
To understand the difference between For of and For in loop read the article Understanding JavaScript Loops: for...in vs for...
Syntax
for (variable in object) {
// statement
}variable: A variable that will be assigned the key (property name) of each iterated property.object: The object whose enumerable properties are iterated over.
The for...in loop is particularly useful for iterating over the properties of an object, allowing you to access both the property names (keys) and their values.
Best Practices
Object Check: Ensure you are iterating over objects and not arrays, as for...in is not meant for array iteration (use for...of or array methods like forEach for arrays).
Own Properties Check: Use hasOwnProperty to filter out properties inherited through the prototype chain if needed.
The for...in loop is particularly useful for iterating over the properties of an object, allowing you to access both the property names (keys) and their values.
Avoid with Arrays: Avoid using for...in with arrays due to potential issues with non-integer keys and inherited properties.
Examples
Let's create a plain object representing a car and use the for...in loop to iterate over its properties:
const car = {
make: "Toyota",
model: "Corolla",
year: 2020,
color: "Red",
};
for (const key in car) {
console.log(`${key}: ${car[key]}`);
}
//Output
make: Toyota;
model: Corolla;
year: 2020;
color: Red;Iterating Over Object Properties:
Iterating over object properties refers to examining each key-value pair in a JavaScript object. This is commonly done using the for...in loop, which iterates over all enumerable properties of an object, including those inherited through the prototype chain. To restrict iteration to an object's own properties, the hasOwnProperty method is used.
const user = {
name: "John",
age: 30,
profession: "Developer",
};
for (const key in user) {
if (user.hasOwnProperty(key)) {
// Ensuring it's an own property
console.log(`${key}: ${user[key]}`);
}
}
// Output:
name: John;
age: 30;
profession: Developer;Iterating Over Inherited Properties:
When you iterate over inherited properties, you are accessing properties that are not defined directly on the object but are inherited from its prototype. This can be done using the for...in loop. To demonstrate:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.profession = "Developer";
const john = new Person("John", 30);
for (const key in john) {
console.log(`${key}: ${john[key]}`);
}
// Output:
name: John;
age: 30;
profession: Developer;Using for...in with Arrays (Not Recommended):
Arrays in JavaScript are best iterated using other methods, such as for...of, forEach(), or traditional for loops, as these provide more predictable outcomes and do not include prototype properties in the iteration. For example:
const numbers = [1, 2, 3, 4, 5];
for (const index in numbers) {
console.log(index);
}
// Output:
// 0
// 1
// 2
// 3
// 4If you want to print both the indices and the values, you can combine the for...in loop with the array access:
const numbers = [1, 2, 3, 4, 5];
for (const index in numbers) {
console.log(`Index: ${index}, Value: ${numbers[index]}`);
}
// Output:
// Index: 0, Value: 1
// Index: 1, Value: 2
// Index: 2, Value: 3
// Index: 3, Value: 4
// Index: 4, Value: 5Working with Maps
The for...in loop is not suitable for iterating over Maps in JavaScript. Instead, you should use the for...of loop to iterate over Maps. However, if you want to iterate over the keys, values, or entries of a Map, you can use the Map's built-in methods: keys(), values(), and entries(), combined with the for...of loop.
Iterating Over Keys:
const userRoles = new Map();
userRoles.set("John", "Admin");
userRoles.set("Jane", "Editor");
userRoles.set("Doe", "Viewer");
for (const key of userRoles.keys()) {
console.log(key);
}
// Output:
// John
// Jane
// DoeIterating Over Values:
const userRoles = new Map();
userRoles.set("John", "Admin");
userRoles.set("Jane", "Editor");
userRoles.set("Doe", "Viewer");
for (const value of userRoles.values()) {
console.log(value);
}
// Output:
// Admin
// EditorIterating Over Entries:
const userRoles = new Map();
userRoles.set("John", "Admin");
userRoles.set("Jane", "Editor");
userRoles.set("Doe", "Viewer");
for (const [key, value] of userRoles.entries()) {
console.log(`${key}: ${value}`);
}
// Output:
// John: Admin
// Jane: Editor
// Doe: ViewerIterating Directly Over the Map (Entries by Default):
You can iterate directly over a Map in JavaScript using a for...of loop. By default, this loop provides each entry as a [key, value] pair:
const userRoles = new Map();
userRoles.set("John", "Admin");
userRoles.set("Jane", "Editor");
userRoles.set("Doe", "Viewer");
for (const [key, value] of userRoles) {
console.log(`${key}: ${value}`);
}
// Output:
// John: Admin
// Jane: Editor
// Doe: ViewerforEach Loop
The forEach loop is a method available on arrays and other iterable collections (like Maps and Sets) in JavaScript. It allows you to execute a provided function once for each array element.
The forEach method requires a callback function that will be executed once for each element in the array. This callback function can take up to three arguments:
Syntax
array.forEach(function (element, index, array) {
// statement
});element: The current element being processed in the array.index(optional): The index of the current element being processed in the array.array(optional): The array thatforEachwas called upon.
The forEach method is particularly useful when you need to perform a specific action for each element in an array, such as logging values, updating elements, or performing calculations.
Basic Iteration Over an Array:
const numbers = [1, 2, 3, 4, 5];
/* you can write this also
numbers.forEach(function (item) {})
*/
numbers.forEach((number) => {
console.log(number);
});
// Output:
// 1
// 2
// 3
// 4
// 5Using Index and Array Parameters:
const numbers = [1, 2, 3, 4, 5];
numbers.forEach((number, index) => {
console.log(`Index: ${index}, Value: ${number}`);
});
// Output:
// Index: 0, Value: 1
// Index: 1, Value: 2
// Index: 2, Value: 3
// Index: 3, Value: 4
// Index: 4, Value: 5Modifying Elements:
let numbers = [1, 2, 3, 4, 5];
numbers.forEach((number, index, arr) => {
arr[index] = number * 2;
});
console.log(numbers);
// Output: [2, 4, 6, 8, 10]Working with Maps and Sets
Using forEach with a Map:
const userRoles = new Map();
userRoles.set("John", "Admin");
userRoles.set("Jane", "Editor");
userRoles.set("Doe", "Viewer");
userRoles.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
// Output:
// John: Admin
// Jane: Editor
// Doe: ViewerUsing forEach with a Set:
const uniqueNumbers = new Set([1, 2, 3, 4, 5]);
uniqueNumbers.forEach((value) => {
console.log(value);
});
// Output:
// 1
// 2
// 3
// 4
// 5Function Passing Techniques
Passing functions to the forEach method is a common practice in JavaScript. You can pass both named and anonymous functions as the callback function for forEach. Here's how you can do it with various examples:
Using Anonymous Functions
You can pass an anonymous function directly to the forEach method.
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(function (number) {
console.log(number);
});
// Output:
// 1
// 2
// 3
// 4
// 5Using Arrow Functions
Arrow functions provide a concise syntax for writing functions.
const numbers = [1, 2, 3, 4, 5];
numbers.forEach((number) => {
console.log(number);
});
// Output:
// 1
// 2
// 3
// 4
// 5Using Named Functions*
You can define a named function and pass it to the forEach method.
const numbers = [1, 2, 3, 4, 5];
function logNumber(number) {
console.log(number);
}
numbers.forEach(logNumber);
// Output:
// 1
// 2
// 3
// 4
// 5Using Named Functions with Additional Parameters
If your named function needs additional parameters, you can create a higher-order function that returns a function with the required parameters.
const numbers = [1, 2, 3, 4, 5];
function createLogger(prefix) {
return function (number) {
console.log(`${prefix}: ${number}`);
};
}
const logWithPrefix = createLogger("Number");
numbers.forEach(logWithPrefix);
// Output:
// Number: 1
// Number: 2
// Number: 3
// Number: 4
// Number: 5Best Practices
When using forEach, keep the following best practices in mind:
- Side Effects: Use
forEachfor performing actions that produce side effects, like modifying elements, logging, or updating the DOM. - Avoid Returns:
forEachis not designed for returning values or constructing new arrays. Usemap,filter, orreducefor these purposes. - Arrow Functions: Use arrow functions for concise syntax, especially for simple operations.
Conclusion
Passing functions to the forEach loop provides flexibility and reusability in your code. You can use anonymous functions, arrow functions, named functions, and even higher-order functions to achieve different behaviors during iteration. This makes the forEach method a powerful tool for performing operations on arrays and other iterable collections.
Differences Between forEach and Other Loops
- NoEarly Exit: Unlike
for,for...of, orfor...inloops, theforEachmethod cannot be broken out of usingbreakorreturn. It will iterate over all elements unless an exception is thrown. - NoReturn Value: The
forEachmethod always returnsundefined. It is designed to perform side effects rather than to transform data. - Simplicity:
forEachprovides a simple and readable way to iterate over arrays and collections, especially when you don’t need to construct new arrays or handle return values.
Working with Array of Objects
When you have an array of objects, you can use the forEach method (or other iteration methods) to iterate over each object in the array and perform operations on its properties. Here are various ways to iterate over an array of objects:
Using forEach Method
Example 1: Logging Each Object
const users = [
{ name: "John", age: 30, profession: "Developer" },
{ name: "Jane", age: 25, profession: "Designer" },
{ name: "Doe", age: 22, profession: "Tester" },
];
users.forEach((user) => {
console.log(user);
});
// Output:
// { name: 'John', age: 30, profession: 'Developer' }
// { name: 'Jane', age: 25, profession: 'Designer' }
// { name: 'Doe', age: 22, profession: 'Tester' }Example 2: Logging Specific Properties
users.forEach((user) => {
console.log(`Name: ${user.name}, Age: ${user.age}`);
});
// Output:
// Name: John, Age: 30
// Name: Jane, Age: 25
// Name: Doe, Age: 22Using map Method
The map method creates a new array with the results of calling a provided function on every element in the calling array.
const names = users.map((user) => user.name);
console.log(names);
// Output: ['John', 'Jane', 'Doe']Using for...of Loop
The for...of loop is another way to iterate over an array of objects.
for (const user of users) {
console.log(Name: ${user.name}, Age: ${user.age});
}
// Output:
// Name: John, Age: 30
// Name: Jane, Age: 25
// Name: Doe, Age: 22Using for Loop
You can also use the traditional for loop.
for (let i = 0; i < users.length; i++) {
console.log(`Name: ${users[i].name}, Age: ${users[i].age}`);
}
// Output:
// Name: John, Age: 30
// Name: Jane, Age: 25
// Name: Doe, Age: 22Using reduce Method
The reduce method can be used to accumulate values based on the objects in the array.
Examples:
Summing Ages
const totalAge = users.reduce((sum, user) => sum + user.age, 0);
console.log(totalAge);
// Output: 77Combining Iteration with Conditionals
You can combine iteration with conditional statements to filter or process specific objects.
Example: Filtering and Logging Specific Users
users.forEach((user) => {
if (user.age > 24) {
console.log(user);
}
});
// Output:
// { name: 'John', age: 30, profession: 'Developer' }
// { name: 'Jane', age: 25, profession: 'Designer' }Conclusion
Iterating over an array of objects can be done using various methods in JavaScript, each with its own advantages:
forEach: Simple iteration for performing actions on each element.map: Creates a new array by applying a function to each element.for...of: Clean and readable syntax for iterating over iterable objects.for: Traditional loop that provides full control over the iteration process.reduce: Accumulates values based on the elements in the array.