1569042459
A powerful feature i’m going to talk about in this article utilizes functions, called a higher order function. A higher order function is a function that either takes another function as an argument or returns a function as the return value. I’m also going to be showing some powerful examples and use cases using them, which is what most tutorials are missing. But no worries, you will find examples in this post.
With that said, if you’ve been playing with JavaScript you probably already heard of the term before. Higher order functions are widely used in JavaScript and they exist in commonly used functions like .map
, .filter
, .reduce
and .forEach
.
If you’re a little new to JavaScript you might be confused as to where those higher order functions are in those methods.
You see these when you declare function callbacks as arguments to these array methods:
const arr = [1, 2, 3, 4, 5, 'six', 'seven', 'eight', 'nine', 'ten']
// Duplicate the array
arr.map(function(value) {
return value
})
// Return only the number types
arr.filter(function(value) {
return typeof value === 'number'
})
// Log each value to the console
arr.forEach(function(value) {
console.log(value)
})
// Add the numbers together, avoiding the string types
arr.reduce(function(acc, value) {
if (typeof value === 'number') {
acc += value
}
return acc
}, 0)
But the higher order function isn’t the function you pass in to methods like .map
. Methods like .map
is the higher order function.
When we mentioned that higher order functions can be functions that take another function as an argument, this is exactly what it was doing when you passed in a function.
Here is an implementation that functions exactly like the .map
method does:
function map(callback) {
const result = []
for (let index = 0; index < this.length; index++) {
const currentItem = this[index]
const returnValue = callback(currentItem, index, this)
result.push(returnValue)
}
return result
}
Looking at the code snippet, the callback
parameter is the exact same function we passed in as an argument to the .map
method I showed earlier:
// Duplicate the array
arr.map(function(value) {
return value
})
To be more precise, let me rename the exact piece of code to the same name as our map
function implementation so you can see it more clearly:
const callback = function(value) {
return value
}
// Duplicate the array
arr.map(callback)
// is the same callback used in our .map implementation:
function map(callback) {
const result = []
for (let index = 0; index < this.length; index++) {
const currentItem = this[index]
const returnValue = callback(currentItem, index, this)
result.push(returnValue)
}
return result
}
At first, it may seem like a useless way to write code in JavaScript. Why pass in a function and bother returning another function, when you can just avoid all of that and do everything in one function all at once?
The biggest benefit that higher order functions bring to the table are reusability and simplicity. But they also benefit from writing beautiful code. Yes, there are such things as ugly code and beautiful code in JavaScript.
With reusability in mind, it introduces some very powerful code compositions.
Now that we know what higher order functions look like in code, you might be wondering what were some use cases and where do they begin to shine.
Let’s say we have a list of frogs:
const frogsList = [
// Yes, these frogs are intelligent. They know how to use email
{
name: 'bobTheFrog',
email: 'froggy@gmail.com',
age: 2,
gender: 'Male',
widthOfTongue: 3,
},
{
name: 'hippoTheFrog',
email: 'hippo@gmail.com',
age: 10,
gender: 'Male',
widthOfTongue: 11,
},
{
name: 'sally',
email: 'sallyLipstick@gmail.com',
age: 5,
gender: 'Female',
widthOfTongue: 4,
},
{
name: 'george',
email: 'georgeRoseBowl@gmail.com',
age: 11,
gender: 'Male',
widthOfTongue: 3,
},
{
name: 'lisa',
email: 'lisaLovesGeorgeForever@gmail.com',
age: 19,
gender: 'Female',
widthOfTongue: 15,
},
{
name: 'kentucky',
email: 'frogInKentucky@yahoo.com',
age: 18,
gender: 'Male',
widthOfTongue: 13,
},
]
To filter the frogs to a specific gender type without a higher order function, we would have to do something like this:
function filterGender(gender, frogs) {
return frogs.filter(function(frog) {
return frog.gender ==== gender
})
}
// filterGender in use
const maleFrogs = filterGender('Male', frogsList)
This is perfectly fine. However, it can be cumbersome if used multiple times in an application. If we had a gigantic app about frogs, filterGender
might be used more than once.
If you were to fetch a different list of frogs you’d have to call filterGender
again and re-declare your gender as the first argument to filter the new list:
function getFrogs() {
// some logic and returns a new list of frogs
}
const newFrogs = getFrogs()
const moreMaleFrogs = filterGender('Male', newFrogs) // Shucks, I have to write 'Male' again?
If you’ve never heard of the DRY principle, I highly recommend to get an understanding of it. Our code snippet violates this rule because of the first argument. We can do better than that.
To solve this issue, we can use the concept of higher order functions.
function filterGender(gender) {
return function(frogs) {
return frogs.filter(function(frog) {
return frog.gender === gender
})
}
}
And now, just like that, we can just assign this gender filterer to a variable and we would never have to declare the same gender when filtering frogs anymore!
const filterFemaleFrogs = filterGender('Female')
const femaleFrogs = filterFemaleFrogs(frogsList)
But wait, that’s not all. Theres an additional benefit we gained from composing them. Not only do we benefit from never having to re-write a filterer for female frogs ever again, but we now also have the ability to re-use the returned function to filter the same gender from different lists of frogs!
Now we can filter females from multiple lists of frogs without having to write as much code:
const frogsList = [
// Yes, these frogs are intelligent. They know how to use email
{
name: 'bobTheFrog',
email: 'froggy@gmail.com',
age: 2,
gender: 'Male',
widthOfTongue: 3,
},
{
name: 'hippoTheFrog',
email: 'hippo@gmail.com',
age: 10,
gender: 'Male',
widthOfTongue: 11,
},
{
name: 'sally',
email: 'sallyLipstick@gmail.com',
age: 5,
gender: 'Female',
widthOfTongue: 4,
},
{
name: 'george',
email: 'georgeRoseBowl@gmail.com',
age: 11,
gender: 'Male',
widthOfTongue: 3,
},
{
name: 'lisa',
email: 'lisaLovesGeorgeForever@gmail.com',
age: 19,
gender: 'Female',
widthOfTongue: 15,
},
{
name: 'kentucky',
email: 'frogInKentucky@yahoo.com',
age: 18,
gender: 'Male',
widthOfTongue: 13,
},
]
const frogsList2 = [
{
name: 'abc',
email: 'froggy@gmail.com',
age: 2,
gender: 'Male',
widthOfTongue: 1,
},
{
name: '123',
email: 'hippo@gmail.com',
age: 10,
gender: 'Male',
widthOfTongue: 4,
},
{
name: 'joe',
email: 'sallyLipstick@aol.com',
age: 5,
gender: 'Female',
widthOfTongue: 6,
},
{
name: 'jennifer',
email: 'georgeRoseBowl@aol.com',
age: 11,
gender: 'Female',
widthOfTongue: 10,
},
]
const frogsList3 = [
{
name: 'professorHammick',
email: 'froggy@gmail.com',
age: 2,
gender: 'Female',
widthOfTongue: 1,
},
{
name: 'macintosh',
email: 'hippo@gmail.com',
age: 10,
gender: 'Female',
widthOfTongue: 6,
},
{
name: 'frogger',
email: 'sallyLipstick@gmail.com',
age: 5,
gender: 'Female',
widthOfTongue: 4,
},
{
name: 'frogNation',
email: 'georgeRoseBowl@gmail.com',
age: 11,
gender: 'Female',
widthOfTongue: 4,
},
]
function gatherFemaleFrogsEverywhere(...frogLists) {
const allFemaleFrogs = []
const filterFemaleFrogs = filterGender('Female')
frogLists.forEach(function(list) {
allFemaleFrogs.push(...filterFemaleFrogs(list))
})
return allFemaleFrogs
}
const females = gatherFemaleFrogsEverywhere(frogsList, frogsList2, frogsList3)
If you still aren’t convinced enough of how powerful higher order functions are in the JavaScript language, then lets continue the example to make an even more generic function to create a higher level of reusability:
function filterFrogs(filter) {
return function(frogs) {
return frogs.filter(filter)
}
}
Previously we had the ability to make a reusable function for a frog’s gender. However, we can go further by abstracting away the logic of the filter
function, so that now we can compose and re-use different filter functions!
const filterMaleFrogs = filterFrogs(function(frog) {
return frog.gender === 'Male'
})
const filterAdultFrogs = filterFrogs(function(frog) {
return frog.age >= 10
})
const filterFrogNamesThatStartWithHippo = filterFrogs(function(frog) {
return frog.name.toLowerCase().startsWith('hippo')
})
const filterGmailEmails = filterFrogs(function(frog) {
return /gmail.com/i.test(frog.email)
})
Wow!
Previously we had the amazing ability to re-use a gender filterer function without ever having to declare the same gender type ever again, but now we have the additional abilities of creating and re-using functions of how we want the frogs to be filtered! Amazing!
We can even use them all at once:
function applyAllFilters(...filters) {
return function(frogs) {
let newFrogs = [...frogs]
for (let index = 0; index < filters.length; index++) {
const filter = filters[index]
newFrogs = filter(newFrogs)
}
return newFrogs
}
}
const applyFrogFilterers = applyAllFilters(
filterMaleFrogs,
filterAdultFrogs,
filterFrogNamesThatStartWithHippo,
filterGmailEmails,
)
const combinedFrogsList = [...frogsList, ...frogsList2, ...frogsList3]
const filteredFrogs = applyFrogFilterers(combinedFrogsList)
console.log(filteredFrogs)
/*
result:
{
age: 10,
email: "hippo@gmail.com",
gender: "Male",
name: "hippoTheFrog",
widthOfTongue: 11
}
*/
Our applyAllFilters
function does the job quite well. However, for huge lists of frogs it might become a heavy task because it runs filter
multiple times to get the final result.
We can again use the concept of higher order functions to make a simple, reusable higher order function that is able to make one pass through the entire list of frogs by applying the filters at the same time.
To be more clear, have a look at the for loop code and try to see what’s truly happening behind the scenes:
function applyAllFilters(...filters) {
return function(frogs) {
let newFrogs = [...frogs]
for (let index = 0; index < filters.length; index++) {
const filter = filters[index]
newFrogs = filter(newFrogs)
}
return newFrogs
}
}
The line I want you to look at is this:
newFrogs = filter(newFrogs)
That line of code is the same line of code as return frogs.filter(filter)
in this function:
function filterFrogs(filter) {
return function(frogs) {
return frogs.filter(filter)
}
}
This is a problem, because the filter method creates a new array. When we had written this:
const applyFrogFilterers = applyAllFilters(
filterMaleFrogs,
filterAdultFrogs,
filterFrogNamesThatStartWithHippo,
filterGmailEmails,
)
We’re calling the filter method 4 different times. In other words, we’re making JavaScript create four different arrays in memory just to get the final result.
So how can we make JavaScript create just one array to get the same result in the end?
You guessed it. Using higher order functions!
function composeFrogFilterers(...fns) {
return function(frogs) {
return fns.reduce(function(accumulatedFrogs, fn) {
return fn(accumulatedFrogs)
}, frogs)
}
}
const applyFrogFilterers = composeFrogFilterers(
filterMaleFrogs,
filterAdultFrogs,
filterFrogNamesThatStartWithHippo,
filterGmailEmails,
)
const allFilteredFrogs = applyFrogFilterers(combinedFrogsList)
console.log(allFilteredFrogs)
/*
result:
{
age: 10,
email: "hippo@gmail.com",
gender: "Male",
name: "hippoTheFrog",
widthOfTongue: 11
}
*/
I hope you are convinced of how powerful higher order functions are and that by reading this article you gained some more insight on the use cases of this concept! Look out more for more in the future!
===================================================================
Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter
#javascript
1596436980
Higher-order functions are functions that operate on other functions, either by taking them as arguments or by returning them.
There are a lot more higher order functions than what will be covered in this article, but these are good ones to get you up and running as a beginner. These standard array methods are forEach()
, filter()
, map()
and sort()
.
N.B- I’d be using examples to illustrate each method so you can get a clearer picture, and also just printing to the console to keep the examples as simple and basic as possible.
Example: Lets say in an array of a group or friends, and we want to loop through that array and print to the console each element of that array.
Using a for loop ;
const friends = ['Toyin', 'Olumide', 'Fola', 'Tola'];
for ( let i=0; i < friends.length ; i++) {
cosole.log (friends[i])
};
The action same as above can be achieved using theforEach()
method as seen below;
const friends = ['Toyin', 'Olumide', 'Fola', 'Tola'];
friends.forEach(function(name) {
console.log(name)
};
What the forEach()
method simply does is to take in a function as an argument and loop through each item in the array without using iteration[i].
This is really awesome when the ES6 arrow functions are used, our code is reduced to a single line that is clean and maintainable. As seen below:
const friends = ['Toyin', 'Olumide', 'Fola', 'Tola'];
friends.forEach(name => console.log (name));
2. **_filter( ) : _**Just like the name implies, it is used to filter out elements of an array that do not meet the conditions set in the callback function passed as an argument. The callback function passed to the filter()
method accepts 3 parameters: element
, index
, and array
, but most times only the element
parameter is used.
**Example : **In an array showing a group of friends and their ages, lets say we want to print to the console the friends that can drink assuming the age limit for drinking is 18. Using a for loop without high order functions;
const friends = [
{name : 'Toyin', age: 24},
{name : 'Olumide', age: 14},
{name : 'Fola', age: 12},
{name : 'David', age: 42}
];
for ( let i=0 ; i<friends.length ; i++) {
if (friends[i].age > 18) {
console.log(`${friends[i].name} can drink`);
}
};
Now using the filter()
method :
const friends = [
{name : 'Toyin', age: 24},
{name : 'Olumide', age: 14},
{name : 'Fola', age: 12},
{name : 'David', age: 42}
];
friends.filter (function (friend) {
if (friend.age > 18){
return true;
}
});
#functional-programming #beginners-guide #javascript #higher-order-function #es5-vs-es6 #function
1595831640
A Better Take on JavaScript’s Higher Order Functions.
Functional Programming is awesome! It makes programming fun.
Learning to program “functionally” is going to make you a fantastic programmer and you will feel secure with the quality of your work.
You will be able to write your programs with fewer bugs and in less time because you will be able to re-use your code.
Within this paradigm, we will focus on one of the most important concepts in functional programming, and that is Higher-Order Functions.
So let’s get started!
In JavaScript, and in many functional programming languages, functions are values.
Let’s take a simple function for example:
function double(x) {
return x * 2
}
What is super cool about JavaScript is that we can take this function and make it into an anonymous function to pass it around and re-use it by declaring a variable.
let double = function(x) {
return x * 2
}
let pancake = double
pancake(40) // 80
We declared a variable _double _and assigned it to the anonymous function. Then we declared another variable, pancake, and assign it to the same function. Just like strings and numbers, functions too can be assigned to variables.
So, in functional programming, functions are values and they can be assigned to variables and they can also be passed into other functions.
Functions that operate on other functions, either by taking them as arguments or by returning them, are called higher-order functions. — see Eloquent JavaScript
In other words, as pertaining to our example, higher-order functions can be understood as functions being passed into other functions to do awesome things!!!
Sure, that makes sense, right? But what are these good for?
Composition.
The fact that we can take one function and put it into another function allows us to compose a lot of small functions into bigger functions.
Let’s look at how to use one of these higher-order functions. Probably the most basic and useful function is
Filter() is a function on the array that accepts another function as its argument, which it will use to return a new filtered version of the array.
Let’s make a fun array of something.
const pets = [
{ name: 'Flip flop', species: 'rabbit' },
{ name: 'Dino', species: 'dog' },
{ name: 'Ralph', species: 'fish' },
{ name: 'Chuchi', species: 'cat' },
{ name: 'Ari', species: 'dog' },
{ name: 'Spock', species: 'dog' },
{ name: 'ying yang', species: 'cat' },
]
What we want to do here is to just “filter” out all the dogs.
Our output must include Dino, Ari, and Spock. 😆
Question: How would I do this with a normal loop?
#higher-order-function #javascript #security #programming #code-review #function
1605017502
Other then the syntactical differences. The main difference is the way the this keyword behaves? In an arrow function, the this keyword remains the same throughout the life-cycle of the function and is always bound to the value of this in the closest non-arrow parent function. Arrow functions can never be constructor functions so they can never be invoked with the new keyword. And they can never have duplicate named parameters like a regular function not using strict mode.
this.name = "Bob";const person = {
name: “Jon”,<span style="color: #008000">// Regular function</span> func1: <span style="color: #0000ff">function</span> () { console.log(<span style="color: #0000ff">this</span>); }, <span style="color: #008000">// Arrow function</span> func2: () => { console.log(<span style="color: #0000ff">this</span>); }
}
person.func1(); // Call the Regular function
// Output: {name:“Jon”, func1:[Function: func1], func2:[Function: func2]}person.func2(); // Call the Arrow function
// Output: {name:“Bob”}
const person = (name) => console.log("Your name is " + name); const bob = new person("Bob"); // Uncaught TypeError: person is not a constructor
#arrow functions #javascript #regular functions #arrow functions vs normal functions #difference between functions and arrow functions
1595648580
Functional programming is a paradigm that results in cleaner and more concise code, that is easier to maintain, and reduces hard to find bugs. A central concept in functional programming is higher order functions. In JavaScript there a multiple of built in higher order functions.
According to Wikipedia a higher order function does one of the following:
Lets get to it. In enterprise grade software, we sometimes want to filter on cute dogs.
const dogs = [
{ name: 'Cocker spaniel', cute: true },
{ name: 'Chihuahua', cute: false },
{ name: 'Malteser', cute: true },
{ name: 'Tax', cute: false },
]
We could use a for-loop for this. Where we would iterate over each dog and filter based on the cute boolean.
const cuteDogs = [];
for (let i = 0; i < dogs.length; i++) {
if (dogs[i].cute)
cuteDogs.push(dogs[i]);
}
However there is a much simpler solution, that is more elegant, that is using the filter function.
const cuteDogs = dogs.filter(dog => dog.cute);
#javascript #functional-programming #higher-order-function
1625800380
A function expression is another way of creating a function. It makes your code maintainable because each function has its task and it avoids scope pollution - a term used when variables a cluttered within the namespace, thereby making your program more prone to error.
In this tutorial we will learn the function expressions in the following sections:
Official website: https://techstackmedia.com
Watch the entire JavaScript Series, including upcoming JavaScipt videos on YouTube: https://www.youtube.com/playlist?list=PLJGKeg3N9Z_Rgxf1Und7Q0u0cSre6kjif
Check out the article: https://techstack.hashnode.dev/javascript-function-expressions.
Next article: https://techstack.hashnode.dev/javascript-higher-order-functions
Become a patron to learn more: https://www.patreon.com/techstackmedia
Techstack Media is in partnership with Skillshare: http://bit.ly/tsm-skillshare.
Learn anything and get the required skill you need to kickstart a long-lasting career.
Website Request: bello@techstackmedia.com
Social Media:
✅ Facebook: https://facebook.com/techstackmedia
✅ Twitter: https://twitter.com/techstackmedia
✅ Instagram: https://instagram.com/techstackmedia
✅ LinkedIn: https://linkedin.com/in/techstackmedia
#javascriptfunctions #functionexpressions #returnstatements #defaultparameters #functionbody #functionscope #javascriptfunction #arrowfunction #functiondeclaration #functionexpression #anonymousfunction #javascript #techstackmedia #codenewbies #learntocode #tutorial #webdev #DEVCommunity #DEVCommunityIN #NodeJS #programming #Hashnode #100DaysOfCode #opensource #techstack #media #womenwhocode #dev #blogging #writing #coding #webdevelopment
#javascript #javascriptfunctions #javascript higher-order functions