paint-brush
Higher-Order Function in JavaScript with ES6 Examplesby@marat
429 reads
429 reads

Higher-Order Function in JavaScript with ES6 Examples

by MaratDecember 28th, 2021
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

In this article, we are going to learn higher-order functions in JavaScript, as well as see the ways you can use them. The JavaScript function is a first-class object. The function passed as an argument to a higher-order function is called callback. The key feature of these functions is that they can accept other functions as arguments and/or specify a function as a return value. We call the function from the callback from the function that transfers a specific operation to a specific function that implements this operation.
featured image - Higher-Order Function in JavaScript with ES6 Examples
Marat HackerNoon profile picture


In this article, we are going to learn higher-order functions in JavaScript, as well as see the ways you can use them.


The key feature of higher-order functions is that they can accept other functions as arguments and/or specify a function as a return value. Extraordinary functional methods like these are strong constructs available to you in JavaScript and other high-level languages like Python, Lisp, etc.


The JavaScript function is a first-class object.


There is the concept of first-kind (or class) objects in programming languages. This refers to the values that can be passed to a function, returned from a function, and assigned to variables or constants. These values include data of all types, such as numbers, strings, arrays, booleans, etc.


One should take into account that the variable or constant itself does not fall under this concept, since only the data contained in the variable or constant is considered a first-class object.


Against this background, the following statements will be correct:

  • We can pass the first-class object to a function as an argument
  • We can pass other functions to a higher-order function as an argument


Let’s have a look at the example below:


const function1 = () => {
    console.log("I'm the function1 result");
};

const function2 = (callback) => {
    console.log("I'm the function2 result");

    callback();
};

function2(function1);
// I'm the function2 result
// I'm the function1 result


The function passed as an argument to a higher-order function is called callback.



Here, we are passing function1 as an argument to function2. function1 acts as a callback and it is worth diving deeper into this. But prior to that, let's look at an example that doesn't use a callback:


const calculate = (x, y, operation) => {
    if (operation === 'subtract') {
        return x - y;
    } else if (operation === 'divide') {
        return x / y;
    }
};

console.log(calculate(10, 3, 'subtract'));
// 7


Suppose the above calculate function makes a part of a library like jQuery. In the current implementation, the function supports 2 types of calculations: division and subtraction. But what if we also need, for example, addition or multiplication operations? In this case, you will have to search for another library, since we cannot add the required calculation methods to the library.


But there is another option, which lies in making the calculate function more abstract. For this, we need to expose the functionality through a callback.


Let's add a callback to the example mentioned above. This will not only improve our code but also allow us to visually evaluate the callback features:


// Library function
const calculate = (x, y, callback) => {
    if (typeof callback === 'function') {
        return callback(x, y);
    };
};

// Functions that we will pass as callback
const add = (x, y) => {
    return x + y;
};

const substract = (x, y) => {
    return x - y;
};

const multiplay = (x, y) => {
    return x * y;
};

const divide = (x, y) => {
    return x / y;
};

// We call the function from the library and pass the callback
console.log(calculate(12, 8, add));
// 20


Under this approach, we transfer not just a specific operation to the library but a function that implements this operation. And now it only takes to run it to get the result.


Take a look at a real-life example: let’s sort the array by keys in ascending order using the sort() method:


const someArray = [
    {
        key: 12,
        value: 'Hello',
    },
    {
        key: 14,
        value: 'Something',
    },
    {
        key: 13,
        value: 'World',
    },
];

someArray.sort((valueA, valueB) => {
    if (valueA.key < valueB.key) {
        return -1;
    } else {
        return 1;
    }
});

someArray.forEach((value) => {
    console.log(`${value.key} ${value.value}`)
});
// 12 Hello
// 13 World
// 14 Something


If we need to sort the array in descending order by values, the code would look like this:


someArray.sort((valueA, valueB) => {
    if (valueA.value > valueB.value) {
        return -1;
    } else {
        return 1;
    }
});

simpleArray.forEach((value) =>
    console.log(`${value.key} ${value.value}`)
);

// 13 World
// 14 Something
// 12 Hello


In the above examples, we used simple functions. However, when they are passed as arguments to other functions, they can take part in more complex functions in an unexpected way.


I hope this article was helpful and you will use callbacks more frequently in your projects.