DEV Community

Cover image for Difference between callback functions and high order functions in JavaScript
Vincent Kipyegon
Vincent Kipyegon

Posted on • Edited on

Difference between callback functions and high order functions in JavaScript

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(){}

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

const myFunc=function(){}

  1. 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:

// 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);


Enter fullscreen mode Exit fullscreen mode

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.

/** 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");
});
Enter fullscreen mode Exit fullscreen mode

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.

// 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
Enter fullscreen mode Exit fullscreen mode

array filter

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

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);

Enter fullscreen mode Exit fullscreen mode

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.

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);
Enter fullscreen mode Exit fullscreen mode

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.

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);
Enter fullscreen mode Exit fullscreen mode

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.

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

if(element) element.addEventListener("click",handleClick)
Enter fullscreen mode Exit fullscreen mode

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.

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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.

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>
  );
}

Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)