JavaScript Concepts 101: Higher-Order Functions
Hey guys! As I continue my coding journey, I have discovered a big gap in my learning: although I can churn out code and debug like nobody’s business, I have a really hard time explaining the more conceptual basics of how JavaScript and other coding languages work. So, I decided to make a series of blogs to take the time to break down these concepts for myself, with the hopes that I can help someone else along the way! Concept number one: higher-order functions.
What is a higher-order function?
I got my favorite definition from freeCodeCamp: According to them, a higher-order function is:
A function that accepts and/or returns another function.
What that means is that higher order functions will either a)take a function as a parameter or b)return another function when it is run.
But, How Does This Even Work?
JavaScript loves functions. So much so that JavaScript treats a function like a special type of object. The most common way I see this in practice is setting functions as variables:
const hello = function(name) {
console.log('Hello, ${name}!')
}
Basically, anything you would do with any other sort of data (strings, booleans, etc.) you can also do with a function in JavaScript. Let’s see some examples of these higher order functions in action:
Taking a Function as an Argument
These are the types of higher-order functions that you are probably already using frequently in everyday life and didn’t even realize what they were: iterators. Array.prototype.map, Array.prototype.filter, Array.prototype.reduce, you name it. Let’s break it down with the .map iterator:
function doubledArray(array) {
array.map(num => num * 2)
}
This is a simple iterator that maps over an array of numbers and returns an array with each number in the array doubled. We probably could all crank this syntax out in our sleep, but when you get down to the nitty gritty, the argument inside the .map function is another function. Let’s look at this a different way:
let doubler = num => {
return num * 2
}function doubledArray(array) {
array.map(doubler)
}
We are doing the exact same thing as before, but this time just pulling out the function that doubles a number and then calling on it inside the doubled array function The first example is recommended for cleaner code of course, but breaking it down like this helps me really understand what these iterators are doing!
Returning Another Function
Most frequently, I see this type of higher-order function when I’m using Redux when building out React components:
export default connect(mapStateToProps, mapDispatchToProps)(App);
In this example, connect is a function that we pull from the react-redux library. The arguments mapStateToProps and mapDispatchToProps are also functions, but they are essentially just return values. They are then connected to the App component using what is called double invocation (which I would like to dive deeper into in a future blog).
*** To be honest, this type of higher-order function is still a little confusing to me and I definitely need to do some more reading! ***
Benefits of Higher-Order Functions
Let’s think back to the iterators we discussed above. Before using those higher-order functions, how would we transform an array? For me personally, I would probably use a for loop, and put the conditionals and any other sort of needed code inside that. Although this of course still works, it’s more code, and there’s more room for error.
I hope this blog helped with your understanding of the concept of Higher-Order Functions! Please let me know what you think — I am still learning too!