Difference between callback functions and high order functions in JavaScript
Tags: webdev, javascript, react, functional
Published: 2023-02-20 09:08:50

Functions in Javascript are a piece of self-contained code tat performs a given task. Most JavaScript interviews put off potential employees with a  difference between callback function and high order functions. 

These 2 concepts are powerhouse of  JavaScript and work horse of node.js; understanding them is not only key to writing scalable code but also key to having comprehensive knowledge of  how JS language and node.js works under the hood.

Lets first look at types of JS functions.

There are 3 types of functions  in JavaScript:

1.  **Function declarations** are functions that starts with function keyword followed by an optional name, parenthesis and body enclosed by curly braces.

`function myFunc(){}`

2. **Function expression** is a function declaration  without a name  declaration but assigned to a variable. Like so 


`const myFunc=function(){}`

3. **Arrow functions** are function expression that have a neat and clean syntax; a variable  is assigned a parenthesis, followed  an arrow sign and a body enclosed with curly braces.

`const myFunc=()=>{}`

Callback functions and high order functions are **features** of JavaScript functions; a **Callback** is a function passed to another function as an argument while a **high order function** is a function that accepts another function as argument  (callback) and/or returns a function. They are used simultaneously;where there is a callback there is a high order function or vice versa.

Let's look at an example:

```javascript
// call back
const PopulateDom = () => {
  console.log("Call back invoked");
};

function mainFunction(callback) {
  // assume you want to perform an asunchronous operation; say data fetching from the server...

  // then when data arrives, just call callback function to handle
  callback();
}
// then invoke main function and pass PopulateDoM function as argument without invoking it

mainFunction(PopulateDom);


```
The *MainFunction* above takes a parameter called callback which is reference to a function that will be passed during invocation.The *populateDom* is therefore a callback function supplied to mainFunction.

An **anonymous function** is just a function declaration without a name; they are typically used as callbacks and are defined inline with the function that will receive them as arguments when they are invoked.



```javascript
/** Invoke main function with an anonymous arrow function */
mainFunction(() => {
  console.log("Call back invoked");
});
/** Invoke main function with an anonymous function declaration */
mainFunction(function () {
  console.log("Call back invoked");
});
```


Main function above is a high order function; as it receives a callback. Javascript has a lot of inbuilt  high order functions that receive functions as argument. 


Array methods: `map,filter,reduce,find,some,every,forEach etc` are high order array functions that take a callback function and performs some given operations.

### array map

Map method loops though each item in an array,takes a callback, then returns the whole array.

```javascript
// lets get  the powers of two of array elements above
const nums = [3, 4, 6, 7, 8, 10];
const powersOfNums = nums.map((num) => num ** 2);
// alternative 1
const _powersOfNums = nums.map(function (num) {
  return num ** 2;
});
// alternative 2
function getPowers(num) {
  return num ** 2;
}
const __powersOfNums = nums.map(getPowers); // another alternative
```


### array filter

Filter method filters out items in array depending on given condition.

```javascript
const nums = [3, 4, 6, 7, 8, 10];
// lets get numbers divisible by 2 from the array above

const divisibleByTwo = nums.filter((num) => num % 2 === 0);
// alt 1
const _divisibleByTwo = nums.filter(function (num) {
  return num % 2 === 0;
});

// alt 2
const getDivisibles = (num) => {
  return num % 2 === 0;
};

const __divisibleByTwo = nums.filter(getDivisibles);

```

### Array reduce

Reduce array method takes 2 arguments; a callback function and an optional initial value, then iterates through an array of elements; performs a sum if its number or concatenation if its a string or a returns an object.

```javascript
const nums = [3, 4, 6, 7, 8, 10];
// lets get them sum  all numbers in the array above
const initial = 0;
const sumNums = nums.reduce((a, b) => a + b, initial);
```


Javascript **setTimeout**, **setInterval** and **addEventListener** are also in-built high order functions;setTimeout and setInterval functions perform a given over a given period of time; 

setTimeout executes once  at a given timeout while setInterval executes continously over given time; They take 2 arguments; a callback function and time in milliseconds. Note these functions return a value that can be used to cancel them from executing.

```javascript
const time = 5000;

const timeoutFunction = () => {
  console.log(`I only run once after ${time} seconds.`);
};

const intervalFunction = () => {
  console.log(`I run after every ${time} seconds.`);
};

setTimeout(timeoutFunction, time);

setInterval(intervalFunction, time);
```

**AddEventListener** is a function used to attach event handlers to listen to events on DOM elements; it takes 3 arguments: an event type (string), a callback function and an optional boolean as third argument,defaults to false.

```javascript
const element=document.getElementById("someElement")
function handleClick(e){
// perform some action}

if(element) element.addEventListener("click",handleClick)
```

React, a JavaScript UI library, also uses callbacks and high order functions incessantly in its react hooks.


React `useState`  hook takes an optional callback used whenever you want to track the state of a variable where the next value relies on the previous value.

```javascript
function CounterComponent() {
  const [counter, setCounter] = React.useState(0);
  const handleClick = () => {
    // set counter takes a callback that uses the previous value to calculate the next value
    setCounter((prev) => {
      const next = prev + 1;
      return next;
    });
  };

  return (
    <div>
      <p>
        {" "}
        The count is: <b>{counter}</b>
      </p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}
```

React `useEffect`  hook is a high order function that takes a callback and an option dependency array for watching variable changes. The callback returns an optional function.
The hook performs side effect actions after a component renders and clean up actions just before it unmounts.

```javascript
function CounterComponent() {
  const [counter, setCounter] = React.useState(0);
  const handleClick = () => {
    // set counter takes a callback that uses the previous value to calculate the next value
    setCounter((prev) => {
      const next = prev + 1;
      return next;
    });
  };

  /** for reseting the counter to zero when component unmounts */
  const cleanUpFunction = () => {
    setCounter(0);
  };
  // run after a component mounts and before a component unmounts;
  React.useEffect(() => {
    if (counter === 100) {
      setCounter(0);
    }

    return cleanUpFunction;
  }, [counter]);

  return (
    <div>
      <p>
        {" "}
        The count is: <b>{counter}</b>
      </p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}

```

Understanding callback and high order functions is a gateway to endless possibilities in function programming paradigm.