Hello guys, I'm back with another article in my JavaScript Concepts Simplified series. Today, I'm going to go through the concept of Higher-Order Functions.
This is not necessarily specific to JavaScript per se. But it is an essential concept you must learn when going forward with JavaScript. If you read my article regarding closures, you do already have some experience with higher-order functions even if you do not have an idea.
The term, Higher-Order Functions aka HOFs, is said to be coined way back in 1891.
Useful Terminology
Before learning Higher-Order functions, let's quickly check out few other concepts that would aid you in understanding higher-order functions better.
Functional Programming
Functional programming (often abbreviated FP) is the process of building software by composing pure functions, avoiding shared state, mutable data, and side-effects. Functional programming is declarative rather than imperative, and the application state flows through pure functions. Contrast with object-oriented programming, where application state is usually shared and colocated with methods in objects.
First-Class Functions
In a programming language where functions are treated as variables, it is said to have First-Class functions. In such a language like JS, a function can be passed as an argument to other functions, can be assigned as a value to a variable and can be returned by another function
What is a Higher-Order Function?
A Higher-Order Function is a function that does at least one of the following things.
- Takes one or more functions as arguments
- Returns a function as a result
All the functions that are not higher-order functions are called first-order functions.
Usage
JavaScript has a list of inbuilt HOFs as well as we can write our own HOFs.
Inbuilt Higher-Order Functions
Array filter method
const numbers = [1, 2, 3, 4, 5, 6, 7]
const smallerThanFive = x => x < 5
console.log(numbers.filter(smallerThanFive)) // [1, 2, 3, 4]
As you can see, we are passing a function called smallerThanFive to the filter method as the callback function. Read more on the filter method here.
Array find method
const innings = [
{player: "Sanga", score: 59},
{player: "Mahela", score: 70},
{player: "Angie", score: 85}
];
const higherThanSeventyFive = inning => inning.score > 75
console.log(innings.find(higherThanSeventyFive)) //{ player: 'Angie', score: 85 }
As you can see, we are passing a function called higherThanSeventyFive to the find method as the callback function. Read more on the find method here.
Array map method
const numbers = [1, 2, 3, 4]
const multiplyByTwo = x => x * 2
console.log(numbers.map(multiplyByTwo)) // [2, 4, 6, 8]
As you can see, we are passing a function called multiplyByTwo to the map method as the callback function. Read more on the map method here.
The list goes on and on. I'd like to recommend you to check out the MDN Docs articles on Array methods to learn more.
Custom Higher-Order Functions
Since all the above examples were about passing functions as parameters, let's make our own higher-order function return a function.
const multiply = (firstValue) => (secondValue) => firstValue * secondValue
Let me write this without the arrow function syntax to make things a bit clearer for you.
function multiply (firstValue) {
return function (secondValue){
return firstValue * secondValue;
}
}
The multiply function gets the firstValue as an argument and returns a function that asks for the secondValue as an argument. Here is how you call this function.
multiply(10)(20) //Returns 200
Some of you might be thinking, "We can just write this in a single function and pass both values into that. Why did you use a higher-order function for this?". Yes, you are right. There is no need for writing a higher-order function to multiply two values.
But, if you want to make the inner functions not accessible to the outside, you can write a higher-order function. And learning to write higher-order functions would save you a lot of time.
I know this could be hard to grasp, especially if you are new to functional programming. I believe you understand what is happening in the above function. But some of you might not still understand the thinking process behind writing a higher-order function like this.
Let me take you through the thinking process so that you can attempt writing your own higher-order function.
Explaining The Thought Process
function multiply (firstValue) {
//Do some stuff with firstValue
}
multiply(10)
Here you have a normal function that takes in an argument called firstValue. And then you realize that you have to write another function, but you don't want to make it accessible from the outside. So, what are your options?
function multiply (firstValue) {
//Do some stuff with firstValue
return function (secondValue) {
//Do some stuff with firstValue and secondValue
}
}
multiply(10)(20)
You can write it as a nested function. But then, there is no way for you to pass arguments from outside (You can pass the value to the outer function and then pass it to the inner function. But that is not a good coding practice). What you can do is to return the inner function and take in an argument from the inner function. Likewise, you can just keep writing functions inside functions as much as you need.
Conclusion
To sum things up, higher-order functions are just like regular functions in JavaScript. The only difference is that while the regular functions take in variables and return variables, Higher-Order functions take in functions and return functions.
I hope you learned something valuable from Today's article. If you liked it, drop a like and follow me so that you don't miss the upcoming articles. And as always, stay safe guys 😷
Top comments (0)