Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Higher-Order Functions In JavaScript
Oluwatobi Adedeji
Oluwatobi Adedeji

Posted on

     

Higher-Order Functions In JavaScript

One of the sweet things I really enjoy about JavaScript is the fact that it is a multi-paradigm programming language, you can
apply different paradigms of programming; object-oriented, functional, event-driven, etc
Although most times, we tend to treat JavaScript as a functional programming language based on our preference, one of the things
When dealing with JavaScript as a functional programming language, we need to note that we cannot be mutating states or change values assigned to variables.
A way we can achieve this is by using higher-order functions.

Before we begin to talk about higher-order functions in JavaScript let's understand some basic concepts about JavaScript that
will make reading this article easy to follow. Concepts like:

  • declaring functions in JavaScript
  • function arguments in JavaScript
  • function return type
  • functions in JavaScript as a first-class citizen

And later in this article, we will be touching:
-higher-order functions in JavaScript
-examples of higher-order functions in JavaScript

  • use cases of high-order functions in solving problems in JavaScript
  • writing your own higher-order functions in JavaScript
  • Let's also play around with writing some built-in higher-order functions in JavaScript.

Let's dive in,

Declaring Functions in #"our first function")}//So when we want to make use of the function :firstFunction()

Enter fullscreen modeExit fullscreen mode

We just wrote a basic function, let's continue:
Let's write a function that can sum up two numbers; we will need two arguments, parameters are used when a function is declared but arguments are used when the function is called

// Definition:function sumTwoNumbers(num1,num2){  const sum = num1 + num2   return sum}//Let's call the function://Here we will pass the parameters which are in this case the two //numbers we want to add togetherconsole.log(sumTwoNumbers(3,7)// The result we have is 10
Enter fullscreen modeExit fullscreen mode

And the result will always be consistent and correct as long as nothing goes wrong in the function block

In the function we just wrote to sum up two numbers, we are actually returning the sum of the two numbers.. One thing we need to take note of is that
whenever we have a return statement in a function, the function stops executing at that point, we will make use of this later..

Functions in JavaScript can be treated as first-class citizens, what I am saying here is that functions can be treated as a variable in JavaScript, let me explain this
using the previous functions we have written.

//The first function we wrote can be written as :const firstFunction = ()=>{console.log("our first function")}
Enter fullscreen modeExit fullscreen mode

You notice we are declaring our function as a variable here, let's also re-write the second function

const sumTwoNumbers = (num1,num2) => num1 + num2
Enter fullscreen modeExit fullscreen mode

This looks shorter right? Let me explain what is happening here, instead of writing long lines of code, if you want to write a function that does not require
multiple lines of logic, you also notice we don't explicitly write a return statement but as far as there is no curly brace after the big fat arrow, the function
returns the value of _num1 + num2
_

We can now safely move on to higher-order functions in #"http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24">Enter fullscreen modeExit fullscreen mode

Array.map() :
a map function is used to map through an array, but unlike the regularforEach or for, map function returns an array

For Example, let's say we want to add two to every number in an array of numbers

If we want to do this with our regularforEach, we will do it this way:

const numArr = [1,2,3,4,5,6,7,8,9,10]const newNumArr = []numArr.forEach((num)=>{    newNumArr.push(num + 2)})console.log(newNumArr)
Enter fullscreen modeExit fullscreen mode

We get the result we want but, remember if we are doing functional programming at its core, we wouldn't want to be mutating state..
This is now where we can make use of a higher-order function:

const numArr = [1,2,3,4,5,6,7,8,9,10]const newNumArr = numArr.map(num => num + 2)console.log(newNumArr)
Enter fullscreen modeExit fullscreen mode

Apart from that the code is more readable and precise, you should also notice that we do not have reason to reassign or mutate any variable..
That's one of the reasons we use higher-order function

Array.reduce()

Let's say we want to want to add all the numbers in an array of numbers, using ourforEach loop, we would write something like this:

const numArr = [1,2,3,4,5,6,7,8,9,10]let accumulatedSum = 0numArr.forEach(num => {    accumulatedSum += num}    )console.log(accumulatedSum)
Enter fullscreen modeExit fullscreen mode

ThoughforEach is still a higher-order function but remember we want to avoid mutating states..

We can use thereduce() function to achieve what we want :

const numArr = [1,2,3,4,5,6,7,8,9,10]const arrSum = numArr.reduce((accumulator,currentValue)=> accumulator + currentValue,0)console.log(arrSum)
Enter fullscreen modeExit fullscreen mode

In case you have not used the reduce function before, let me explain;

Thereduce() method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.

The first time that the callback is run there is no "return value of the previous calculation". If supplied, an initial value may be used in its place. Otherwise, the array element at index 0 is used as the initial value and iteration starts from the next element (index 1 instead of index 0).

callbackFunction
A function to execute for each element in the array. Its return value becomes the value of the accumulator parameter on the next invocation ofcallbackFunction. For the last invocation, the return value becomes the return value of reduce().

The function is called with the following arguments:

accumulator
The value resulting from the previous call tocallbackFunction. On the first call,initialValue if specified, otherwise the value of array[0].

currentValue
The value of the current element. On the first call, the value of array[0] if aninitialValue was specified, otherwise the value of array[1].

currentIndex
The index position ofcurrentValue in the array. On the first call, 0 ifinitialValue was specified, otherwise 1.

array
The arrayreduce() was called upon.

initialValue Optional
A value to whichaccumulator is initialized the first time the callback is called. IfinitialValue is specified,callbackFunction starts executing with the first value in the array ascurrentValue. IfinitialValue is not specified,accumulator is initialized to the first value in the array, andcallbackFunctiion starts executing with the second value in the array ascurrentValue. In this case, if the array is empty (so that there's no first value to return asaccumulator), an error is thrown.

So the complete syntax for reduce is

Array.reduce((accumulator,currentValue,currentIndex)=>{// write your reducer logic here},initialValue)
Enter fullscreen modeExit fullscreen mode

We can perform a few more complex tasks usingreduce():

Let's say we have an array containing the objects of the student's name, age, and state of origin and we want to have a method that we can use to group the student list
by any of the three fields(name,age orstate of origin)

const students = [    { name: "Mike", age: 10,stateOfOrigin:"Niger" },    { name: "Max", age: 12,stateOfOrigin:"Oyo" },    { name: "Jane", age: 15,stateOfOrigin:"Abia" },    { name: "Adora", age: 13,stateOfOrigin:"Benue" },    { name: "Aishat", age: 14, stateOfOrigin: "Rivers" },    { name: "Abu", age: 15,stateOfOrigin:"Adamawa" },    { name: "Abraham", age: 14,stateOfOrigin:"Adamawa" },    { name: "Tunmise", age: 15,stateOfOrigin:"Oyo" },  ];  const groupBy = (studentData,groupByProperty) => {    return studentData.reduce((accumulated,currentObj)=>{        const key = currentObj[groupByProperty]        const currentGroup = accumulated[key] ?? []        return {...accumulated,[key]:[...currentGroup,currentObj]}    },{})  }  const groupedStudentByState = groupBy(students,"stateOfOrigin")  console.log(groupedStudentByState)
Enter fullscreen modeExit fullscreen mode

In the snippet above, we have an array of student data and we also have a function to group the data we have.

In the groupBy function, we are returning the grouped data directly, the function takes in two arguments; the studentData and the groupByProperty, We are using a
reduce() function on the studentData; following the syntax for reduce(), we have a callback function that takes in accumulated data, the current value as parameters,
we also have the initial value which is an empty object { }.

Making your own higher-order function in JavaScript
Let's say you are working on a project with different folders,for example, express js and you have the models, controllers, routes, etc folders
When you write a function and you want to track if an error occurred or not when the function is called, you can pass in acallBack into the function.

For Example

// models/const insertDataToDB = (...args,callBackFn) =>{  db.query(...,[],(err,res)=>{    if(err){    callBackFn(err,null)    }if(res){   callBackFn(null,res)}})}export {insertDataToDB}// controller/import {insertDataToDB} from "../models/..."const insertData = (req,res)=>{   insertDataToDB(req.body,(error,data)=>{    if(error){    res.status(500).json({...error})    }if(data){res.status(200).json({...data})}})}
Enter fullscreen modeExit fullscreen mode

In the insertToDB function, we passed in a callBack into the function so when we call the function in the controller, we can check if an error occured or not and we can respond to the request.

I really hope you have learned a lot through this article, check up some of the code snippets in this article onGitHub do well to like and share this post and also follow me on Twitter and LinkedIn to get more updates from me, thank you see you soon.

Linkedln
Twitter

Top comments(4)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
kaspera profile image
Kasper Andreassen
Loves optimizing and UX. Proud father of two boys and a girl. Scared of exercise and fond of beer.
  • Location
    Denmark
  • Education
    Hogwarts School of Witchcraft and Wizardry
  • Work
    UX Engineer at Enterspeed
  • Joined

Pro tip: You can add syntax highlighting to your code by adding the language after the first ticks (e.g. javascript). Makes it easier to read :-)

consthelloWorld="Hello world";
Enter fullscreen modeExit fullscreen mode
CollapseExpand
 
oluwatobi_ profile image
Oluwatobi Adedeji
Kingdom-minded | Passionate problem solver ✨
  • Education
    Studying Systems Engineering at University of Lagos
  • Work
    Software Engineer(With keen interest for Backend and IOT devices)
  • Joined

Thanks Kasper

CollapseExpand
 
mubzie profile image
Mubarak Rabiu
Frontend Engineer
  • Location
    Lagos, Nigeria.
  • Education
    University of Lagos
  • Pronouns
    He/Him
  • Joined

Nice article Oluwatobi 👏🏽...

I think I need more context to this line if it isn't an oversight.

arguments are used when a function is declared but parameters are used when the function is called

Is argument not used when you want to invoke a function, while parameters are used when you declare the function?

CollapseExpand
 
oluwatobi_ profile image
Oluwatobi Adedeji
Kingdom-minded | Passionate problem solver ✨
  • Education
    Studying Systems Engineering at University of Lagos
  • Work
    Software Engineer(With keen interest for Backend and IOT devices)
  • Joined

Alright Mubarak, that was a mistake it's actually the other way round thank you for the quick notice

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Oluwatobi Adedeji
Kingdom-minded | Passionate problem solver ✨
  • Education
    Studying Systems Engineering at University of Lagos
  • Work
    Software Engineer(With keen interest for Backend and IOT devices)
  • Joined

Trending onDEV CommunityHot

Adam Neves profile image
My First 7 Days at Woovi: Learnings, Surprises, and Open Questions
#career#onboarding#workplace#devjournal
 Precious Kelvin Nwaogu profile image
I Just Launched a Chrome Extension called productivity timer
#javascript#api#productivity#html
Madza profile image
9 Useful Coding Tools Every Developer Should Bookmark 📚🧑‍💻
#webdev#coding#api#productivity
DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp