DEV Community

Cover image for Understanding Higher Order Function
João Guilherme do Amaral Vequiato
João Guilherme do Amaral Vequiato

Posted on • Edited on

Understanding Higher Order Function

Higher Order Function it's a very basic concept (and much important too) but also a little misunderstood.

Let's understand first the concept, the most clear definition, simple and direct that you probably can use in some tecnical interview.

What is Higher Order Function? (aka HOF)

Higher Order Function it's all function that acepts other function as a parameter and/or return one function.

Before we go for a more deep explanation, we can list some important things about HOFs in programing.

  1. Makes our code more declaritive and easy to read.
  2. It's the key concept to more complex concepts in programing, like closures, currying, promises, and others.
  3. We can generalize functions, so we can reuse these in different ways when it's necessary.

Understanding the Higher Order Functions

See the code below:

function copyArrayAndMultiplyBy5(array) {
  const output = [];
  for (let i = 0; i < array.length; i++) {
    output.push(array[i] * 5);
  }
  return output;
}
const myArray = [1,2,3];
const result = copyArrayAndMultiplyBy5(myArray);
Enter fullscreen mode Exit fullscreen mode

Suppose that we want do now one multiplication function for 3, 4.
Or maybe addition, or division. We need to copy and paste various functions, change only the name and the values from 5 to 3, 4 and too the operator from * to + and /.

And if, rather than define in the declaration moment the all behavior of our function, could we define one parameter to receive another function as argument and let the behavior to the execution moment?

In Javascript functions are objects, called first class objects.

If we can pass objects as arguments for one function, we can pass another function too.
Let's edit our code.

function copyArrayAndManipulate(array, fn) {
  const output = [];
  for (let i = 0; i < array.length; i++) {
    output.push(fn(array[i]));
  }
  return output;
}

Enter fullscreen mode Exit fullscreen mode

Now we create a generic function copyArrayAndManipulate, that receives as parameter the array e one function called fn.

We don't know all the function's behavior on your declaration moment, and we don't need to know.

The function copyArrayAndManipulate it's our Higher Order Function, while the function fn that we'll pass in argument is our callback function.

Now we can create our variations in a much easier and dynamic way, without having to copy and paste unnecessary code.

function copyArrayAndManipulate(array, fn) {
  const output = [];
  for (let i = 0; i < array.length; i++) {
    output.push(fn(array[i]));
  }
  return output;
}
function multiplyBy5(input) { 
  return input * 5;
}
function multiplyBy3(input) { 
  return input * 3;
}
function multiplyBy4(input) { 
  return input * 4;
}
const result1 = copyArrayAndManipulate([1, 2, 3], multiplyBy5);
const result2 = copyArrayAndManipulate([1, 2, 3], multiplyBy3);
const result3 = copyArrayAndManipulate([1, 2, 3], multiplyBy4);
Enter fullscreen mode Exit fullscreen mode

Our code stayed much more declarative and legible, because in reading we know exactly that the value of result1 will be the copy of array [1, 2, 3] multiplied by 5, for example.

Ok, this already improve writing of our code avoiding unnecessary code, but we can let the aesthetic better with arrow functions.

function copyArrayAndManipulate(array, fn) {
  const output = [];
  for (let i = 0; i < array.length; i++) {
    output.push(fn(array[i]));
  }
  return output;
}
const multiplyBy5 = (input) => input * 5;
const multiplyBy3 = (input) => input * 3;
const multiplyBy4 = (input) => input * 4;
const result1 = copyArrayAndManipulate([1, 2, 3], multiplyBy5);
const result2 = copyArrayAndManipulate([1, 2, 3], multiplyBy3);
const result3 = copyArrayAndManipulate([1, 2, 3], multiplyBy4);
Enter fullscreen mode Exit fullscreen mode

So much better. But we don't need to store our functions in constants, we can pass these directly. This give to us more dinamism.

function copyArrayAndManipulate(array, fn) {
  const output = [];
  for (let i = 0; i < array.length; i++) {
    output.push(fn(array[i]));
  }
  return output;
}
const result1 = copyArrayAndManipulate([1, 2],(input) => input * 5);
const result2 = copyArrayAndManipulate([1, 2],(input) => input * 3);
const result3 = copyArrayAndManipulate([1, 2],(input) => input * 4);
Enter fullscreen mode Exit fullscreen mode

The most attentive must have noticed a similarity with map function.
Yes, it's exactly how it works. And as map we have another functions very used and known that be HOFs (like filter and reduce).

Conclusion

Higher Order Function it's a simple and important concept, but so much peoples have a little difficult to understand it.

I hope have achieved desmistify this with the better possible way.

See you soon!👋

If you lost:
Understanding classes and prototypes
Understanding closures

Top comments (0)