Higher-Order Functions in JavaScript?

Higher-Order Functions in JavaScript?

Unlocking the Power of Functions: An Introduction to Higher-Order Functions in JavaScript

ยท

4 min read

We know that functions in javascript are First Class Citizens, so we can assign functions to variables as values, pass a function as an argument to another function and return a function from another function.

// function as values
const var1 = function sayHello() {
  console.log("Hello There");
};

var1(); // -> Hello There

// returning function from function
function returnFunction() {
  return function () {
    console.log("I am being return as function");
  };
}

let var2 = returnFunction(); //stores the returned function
var2(); // I am being return as function

// function as argument
function square(num, callback) {
  var result = num * num;
  callback(result);
}

function IAmCallback(result) {
  console.log(result); // 25
}

// passing function as an argument
square(5, IAmCallback); // -> 25

You might be thinking this article is about higher-order functions then why are we reading this, here is the answer.

Higher-order functions are function which takes function as an argument or returns a function. It is called "higher-order" because it operates on functions, rather than just values. This allows for greater flexibility and abstraction in coding.

Example 1:

Let's under the Higher-order function with an Example. Take a look at the code example below.

const numbers = [2, 4, 5, 6, 7, 8, 9, 10];

function square(numbers) {
  let squaredNumbers = [];
  for (let i = 0; i < numbers.length; i++) {
    squaredNumbers.push(numbers[i] * numbers[i]);
  }
  return squaredNumbers;
}

function cube(numbers) {
  let cubedNumbers = [];
  for (let i = 0; i < numbers.length; i++) {
    cubedNumbers.push(numbers[i] * numbers[i] * numbers[i]);
  }
  return cubedNumbers;
}

console.log(square(numbers)); // -> [4, 16, 25, 36, 49, 64, 81, 100];

console.log(cube(numbers)); // -> [ 8,   64, 125, 216,  343, 512, 729, 1000 8,   64, 125, 216,  343, 512, 729, 1000 ]

In the above example, there are two functions square and cube which accepts a list of numbers and returns a new array with squared and cubed values. as you can see in the above example we are repeating code a lot. let's fix this with a higher-order function.

const numbers = [2, 4, 5, 6, 7, 8, 9, 10];

function square(number) {
  return number * number;
}

function cube(number) {
  return number * number;
}

function calculate(numbers, operation) {
  const output = [];
  for (let i = 0; i < numbers.length; i++) {
    output.push(operation(numbers[i]));
  }
  return output;
}
// calling the calculate function with square operation
let squaredNumbers = calculate(numbers, square);
console.log(squaredNumbers); // -> [4, 16, 25, 36, 49, 64, 81, 100];

// calling the calcualte function with cube operation
let cubedNumbers = calculate(numbers, cube);
console.log(cubedNumbers); // -> [ 8,   64, 125, 216,  343, 512, 729, 1000 8,   64, 125, 216,  343, 512, 729, 1000 ]

In the above example, we have three different function square cube and calculate the square and cube the function accepts a number as an argument and returns the square and cube of that number respectively. Things to notice here are the calculate function, which is the higher order function, which accepts a list of numbers, and a function as arguments. It performs the operation we pass as a function on every element of the array. Now we can also create any number of new operations and pass them to calculate functions. Take a look at the example below.

function doubles(number) {
  return 2 * number;
}

let doubledNumbers = calculate(numbers, doubles);
console.log(doubledNumbers); //  [4, 8, 10, 12, 14, 16, 18, 20];

Example 2:

function multiplyBy(factor) {
  return function(number) {
    return number * factor;
  };
}

const double = multiplyBy(2);
console.log(double(5)); // 10

In this example, multiplyBy is a higher-order function that takes a factor and returns a new function. The returned function takes a number and returns the result of multiplying that number by the factor. We can then use the double constant, which is the result of calling multiplyBy(2), to quickly double any number we pass to it.

Examples of Higher-Order Function.

There are lots of in-built higher-order functions in Javascript, like Array.map(), Array.filter(), Array.reduce() setTimeout() etc. We will learn more about them later, but let's look at the example of Array.map(). This function takes a callback function as an argument and returns a new array containing the results of calling the callback function on each element of the original array.

const numbers = [2, 4, 5, 6, 7, 8, 9, 10];
let squaredNumbers = numbers.map(square);
console.log(squaredNumbers);  // ->  [4, 8, 10, 12, 14, 16, 18, 20];

Conclusion ๐Ÿ™‹โ€โ™‚๏ธ๐Ÿ™‹โ€โ™€๏ธ

In conclusion, higher-order functions are a powerful and flexible tool in JavaScript that allows for greater abstraction and code reusability. They operate on functions, either by taking them as arguments or returning them as results and allow for dynamic and flexible behavior in code. Their use can lead to more concise and readable code, making them a valuable tool in any JavaScript programmer's toolkit.

Did you find this article valuable?

Support Ankit Kumar by becoming a sponsor. Any amount is appreciated!