Home/Blog/Programming/Mastering higher-order functions in JavaScript: A complete guide
Home/Blog/Programming/Mastering higher-order functions in JavaScript: A complete guide

Mastering higher-order functions in JavaScript: A complete guide

Ishrat Fatima
Oct 21, 2024
9 min read

Have you ever found yourself writing repetitive code that makes simple tasks feel tedious? In web development, activities like filtering, sorting, and transforming data can quickly become a hassle without the right tools. This is where higher-order functions come into play. A higher-order function is one that either accepts another function as an argument or returns a function as a result. These functions are powerful because they help you write more flexible and reusable code, simplifying your coding process and enhancing your efficiency.

This blog will cover the fundamentals of higher-order functions in JavaScript, including key built-in methods like map(), filter(), reduce(), forEach(), sort(), find(), and every(). You’ll also discover practical examples and use cases, along with takeaway skills that enhance your coding efficiency.

Let’s dive in!

What is a higher-order function?#

A higher-order function in JavaScript is a function that either:

  • Takes one or more functions as arguments

  • Returns a new function

This characteristic makes higher-order functions a cornerstone of functional programming, enabling flexible and reusable code structures.

Syntax of a higher-order function#

Higher-order functions in JavaScript are built on the concept of callbacks. A callback is simply a function passed as an argument to another function, to be executed at a later time. We define a function independently and then pass it as an argument to another function, which handles its execution. The function that accepts the callback is called a higher-order function.

Let’s break down the syntax with a simple example:

function higherOrderFunction(callback) {
// Perform some operations
callback();
}
function callbackFunction() {
console.log("Callback function executed.");
}
// callbackFunction is sent as a parameter to higherOrderFunction
higherOrderFunction(callbackFunction);

In this example:

  • higherOrderFunction accepts a function as an argument (the callback function) and executes it within its body. This allows higherOrderFunction to perform some operations and then call the function provided as an argument.

  • callbackFunction is the function passed as an argument to higherOrderFunction. It is executed inside higherOrderFunction, demonstrating how higher-order functions can invoke functions passed to them.

From Beginner to Expert: Educative’s Ultimate Guide to JavaScript

Cover
Zero to Hero in JavaScript

JavaScript is a popular, in-demand, and widely used programming language today because of its simple syntax, modular nature, and ability to support all modern browsers. This path is perfect for you if you are new to programming. The path will teach you real-world problem-solving techniques and how to write step-by-step solutions in JavaScript. You will start by covering JavaScript's basic syntax and functionality to create basic programs. In the latter half, you will get a detailed overview of object-oriented programming to create scalable, modular, and cleaner code. Moreover, you will get hands-on experience practicing the implementations of commonly used data structures in JavaScript. Finally, you build a Tetris game step by step using modern JavaScript. By the end of this path, you will be able to write real-world programs in JavaScript and start your career as a JavaScript developer.

29hrs
Beginner
23 Challenges
33 Quizzes

Returning a function from a higher-order function#

Higher-order functions can also return a new function as their result. This is another key aspect of higher-order functions, where a function can be dynamically generated based on the operations inside the higher-order function.

Imagine you are building an e-commerce application and want to create a system where you can apply different discount percentages to products. A higher-order function can help generate different discount calculators based on the percentage passed in.

Here’s how we can implement that:

function createDiscount(discountPercentage) {
return function (price) {
return price - (price * discountPercentage / 100);
};
}
// Create discount functions
const tenPercentDiscount = createDiscount(10);
const twentyPercentDiscount = createDiscount(20);
// Apply discounts to product prices
const price1 = 100;
const price2 = 200;
console.log(tenPercentDiscount(price1)); // Output: 90
console.log(twentyPercentDiscount(price2)); // Output: 160

In this example:

  • createDiscount is a higher-order function that takes a discountPercentage as an argument and returns a new function.

  • The returned function takes the price of a product and applies the discount.

  • tenPercentDiscount is a function that applies a 10% discount, and twentyPercentDiscount applies a 20% discount.

  • We can then apply these discount calculators to different product prices in the store, making the system dynamic and reusable.

Built-in higher-order functions in JavaScript#

JavaScript provides several built-in higher-order functions that allow you to work with arrays and objects efficiently. Some of the most commonly used ones include:

  • map(): This generates a new array by transforming each element of the original array with a given function.

  • filter(): This returns a new array containing elements that meet the condition defined by the provided function.

  • reduce(): This combines array elements into a single value by applying a function across them sequentially.

  • forEach(): This runs a specified function on each element in the array, one at a time.

  • find(): This retrieves the first element in the array that meets the condition specified by the provided function.

  • every(): This checks whether all elements in the array satisfy the condition specified by the provided function.

  • sort(): This rearranges the elements of an array based on a sorting function and returns the modified array.

What does the map() do in JavaScript?#

The map() function allows to transform an array by applying a function to each element, returning a new array without modifying the original.

Example: Applying discounts to products in a shopping cart#

Imagine you have a shopping cart with multiple items, and you want to apply a 10% discount to all products in the cart. This is where the map() function comes in handy. The map() function is a built-in higher-order function that allows you to create a new array by applying a provided callback function to each element of the original array. In the following code, we use map() to iterate over each product in the shopping cart, apply the 10% discount to the price, and return a new array discountedCart with the updated prices. Importantly, the original array remains unchanged, as map() always creates and returns a new array without modifying the original data.

Note: In this example, we use an anonymous function—a function without a name—inside the map() method: item => ({ ...item, price: item.price * 0.9 }). Anonymous functions are often used as quick, one-time-use functions, especially when you don’t need to reuse the function elsewhere in the code. In our case, this function takes each item from the cart, applies the discount, and returns the updated price.

const cart = [
{ product: 'Camera', price: 500 },
{ product: 'Headphones', price: 150 },
{ product: 'Smartwatch', price: 300 }
];
// Using a higher-order function (map) to apply a discount
const discountedCart = cart.map(item => ({
...item,
price: item.price * 0.9 // Applying 10% discount
}));
console.log(discountedCart);
// Output: [
// { product: 'Camera', price: 450 },
// { product: 'Headphones', price: 135 },
// { product: 'Smartwatch', price: 270 }
// ]

What is the filter() function in JavaScript?#

The filter() function allows you to create a new array by filtering elements from the original array based on a condition, leaving the original array unchanged. It executes a provided callback function on each element of the array, including only the elements that satisfy the condition into the new array.

Example: Filtering products in a shopping cart#

Imagine you have a shopping cart with several products, and you want to filter out the items that are priced above $300. This is where the filter() function becomes useful. Consider the following code where filter() function iterates over each product in the cart, checks if the price meets the condition (in this case, being greater than or equal to $300), and returns a new array expensiveCart with only those products.

const cart = [
{ product: 'Camera', price: 500 },
{ product: 'Headphones', price: 150 },
{ product: 'Smartwatch', price: 300 }
];
// Using filter() to get items priced $300 or more
const expensiveCart = cart.filter(item => item.price >= 300);
console.log(expensiveCart);
// Output: [
// { product: 'Camera', price: 500 },
// { product: 'Smartwatch', price: 300 }
// ]

How does reduce() work in JavaScript?#

The reduce() function in JavaScript allows you to accumulate or combine all the elements of an array into a single value. It applies a provided callback function to each element of the array, reducing the array to a single result based on the logic defined in the callback. The reduce() function can be used for tasks such as summing numbers, concatenating strings, or even flattening arrays.

Example: Calculating the total price of products in a shopping cart#

Imagine you have a shopping cart, and you want to calculate the total price of all the items. The reduce() function is perfect for this scenario. It will iterate over each product in the cart, add up their prices, and return the total price as a single value.

const cart = [
{ product: 'Camera', price: 500 },
{ product: 'Headphones', price: 150 },
{ product: 'Smartwatch', price: 300 }
];
// Using reduce() to calculate the total price
const totalPrice = cart.reduce((accumulator, item) => accumulator + item.price, 0);
console.log(totalPrice);
// Output: 950

In the above code, the reduce() function starts with an initial value of 0 (the second argument), and then iterates through each product, adding the price of each item to the accumulator. By the end of the iteration, reduce() returns the total price of the products in the cart.

Important: Like map() and filter(), reduce() does not modify the original array but works on accumulating the values into a final result.

Cover
Learn to Code: JavaScript for Absolute Beginners

JavaScript is a versatile programming language that enhances the interactivity and functionality of web pages. It is a core technology alongside HTML and CSS, indispensable for building simple websites as well as complex web applications. This course is a comprehensive introduction to JavaScript programming fundamentals, starting with problem-solving and simple programs. Through hands-on exercises, challenges, and quizzes, you will learn about control structures, loops, strings, arrays, and functions, eventually gaining mastery. By the time you’re done with the course, you will have acquired problem-solving skills, a strong foundation in JavaScript programming, and a solid understanding of control structures, loops, strings, and arrays. This mastery of JavaScript will significantly boost your employability and open doors to diverse career opportunities in software development.

8hrs
Beginner
4 Challenges
6 Quizzes

What is forEach() in JavaScript?#

The forEach() function in JavaScript allows you to execute a provided function once for each array element. Unlike map() or reduce(), the forEach() method doesn’t return a new array or a final value; instead, it is often used to perform operations such as updating, logging, or applying side effects to each element of the array.

Example: Displaying product information in a shopping cart#

Imagine you have a shopping cart and want to display the details of each product (like the name and price) to the user. The forEach() function is perfect for this task because it allows you to loop through each item and perform an action, like printing the details to the console.

const cart = [
{ product: 'Camera', price: 500 },
{ product: 'Headphones', price: 150 },
{ product: 'Smartwatch', price: 300 }
];
// Using forEach() to display product information
cart.forEach(item => {
console.log(`Product: ${item.product}, Price: $${item.price}`);
});
// Output:
// Product: Camera, Price: $500
// Product: Headphones, Price: $150
// Product: Smartwatch, Price: $300

Important: Unlike map() or reduce(), the forEach() function doesn’t return a new array or value, but it’s useful when you need to perform an action on each item in the array. It’s commonly used for tasks such as logging, updating a UI, or performing other side effects on each array element.

Using sort(), find(), and every() together#

The array methods, sort(), find(), and every() can be effectively combined to manipulate and analyze data within an array. For example, in the code below, the shopping cart is processed to sort the products by price using sort(), find the most expensive product using find(), and check if every product costs less than $100 using every(). Additionally, find() is used again to identify a specific product, such as a smartwatch, based on its name.

const cart = [
{ product: 'Camera', price: 500 },
{ product: 'Headphones', price: 150 },
{ product: 'Smartwatch', price: 300 }
];
// Chaining sort() and find()
const mostExpensiveProduct = cart
.sort((a, b) => a.price - b.price) // Sort by price
.find((item, index, array) => index === array.length - 1); // Find the most expensive product
const specificProduct = cart.find(item => item.product === 'Smartwatch'); // Find the smartwatch
const allUnder100 = cart.every(item => item.price < 100); // Check if all products are under $100
console.log('Most Expensive Product:', mostExpensiveProduct);
console.log('Specific Product (Smartwatch):', specificProduct);
console.log('All Products Under $100:', allUnder100);

Practical use cases for higher-order functions#

Higher-order functions can be applied in various scenarios to solve common programming challenges:

  • Event handling: You can pass callback functions to handle user interactions, enabling responsive and interactive applications.
    Example: A click event handler that triggers a function to show a modal.

  • Data transformation: Functions like map(), filter(), and reduce() are invaluable for processing and transforming arrays, allowing for efficient data manipulation.
    Example: Using map() to convert an array of temperatures from Celsius to Fahrenheit.

  • Composability: Higher-order functions facilitate the combination of simple functions to create more complex behavior, using techniques such as function composition.
    Example: Composing a series of functions that validate user input before submission.

Key takeaways for higher-order functions in JavaScript#

By mastering higher-order functions, you’ll gain the following advantages:

  • Flexibility: Create flexible and reusable code that adapts to different requirements.
    Example: A higher-order function that generates different greeting messages based on input.

  • Modularity: Break tasks down into smaller, focused functions that enhance clarity and maintainability.
    Example: A function that processes user data can call smaller functions for validation, formatting, and saving.

  • Reusability: Instead of repeating similar logic, you can pass functions as parameters, reducing redundancy and improving maintainability.
    Example: You can create a generic function for sorting that accepts different comparison functions.

  • Built-in methods: Becoming proficient with built-in methods like map(), filter(), and reduce() will significantly improve your ability to manipulate arrays and objects effectively.
    Example: Using reduce() to sum up all values in an array of numbers.

Next steps!#

As you continue to enhance your knowledge of JavaScript, it's essential to have a structured learning path. A comprehensive JavaScript roadmap can help you understand what to focus on at each stage, from fundamental concepts to more advanced topics like functional programming, modern JavaScript features, and best coding practices. This will not only strengthen your skills but also prepare you for real-world applications and coding interviews. I highly recommend exploring Educative’s course Zero to Hero in JavaScript. This comprehensive course will equip you with essential JavaScript skills, laying a solid foundation that will enhance your understanding of higher-order functions and their practical applications.

To further enhance your JavaScript skills and understanding, here are some recommended blogs that cover various important topics:

Frequently Asked Questions

What is the difference between callbacks and higher-order functions?

A callback is a function that is passed as an argument to another function and is called at a specific point within that function. The purpose of a callback is to allow for code customization or execution at a later time, often in response to events or asynchronous operations.

A higher-order function, on the other hand, is a function that either takes one or more functions as arguments (like callbacks) or returns a function as its result.

What is the difference between closure and higher-order function in JavaScript?

Is setTimeout a higher-order function?

Can we use map and filter together?

What is the reduce function in JavaScript?


  

Free Resources