DEVELOPMENT

JAVASCRIPT

JavaScript Fundamentals: Higher Order Functions

When looking into functons within JavaScript, a term that is likely to come up is Higher Order Functions, here's all you need to know about them.

  • Functions that return other functions or take other functions as arguments.
    • Taking another function as an argument is referred to as a callback function as it is being called back by the higher-order function

For example, the map function

1
;[1, 2, 3, 4].map((num) => num * num) // [1, 4, 9, 16]

Other Examples include forEach, reduce, filter and sort.

If we didn’t have the map higher-order function and had to use normal functions it would look like:

12345678
const base = [1, 2, 3, 4]
const result = []

for (let i = 0; i < base.length; i++) {
  result[i] = base[i] * base[i]
}

console.log(result) // [1, 4, 9, 16]

By using the map higher-order funciton we have to write less code which not only reduces the risks of introducing errors but also makes the code more readable.

Building the puzzle pieces

One of the biggest benefits of using higher-order functions is the ability to mix and match them together. For example, if we wanted to answer the following questions about the below dataset we can write one function that handles one piece of logic and reuse it.

Questions

  1. Average of everyone’s age
  2. Average age of each sex.
  3. Oldest of each sex
12345678910
const people = [
  { name: 'Coner', age: 21, sex: 'M' },
  { name: 'Sandra', age: 40, sex: 'F' },
  { name: 'Jon', age: 60, sex: 'M' },
  { name: 'Emily', age: 16, sex: 'F' },
  { name: 'Fred', age: 55, sex: 'M' },
  { name: 'Liz', age: 26, sex: 'F' },
  { name: 'Bill', age: 10, sex: 'M' },
  { name: 'Susan', age: 30, sex: 'F' },
]

Doing this without higer-order functions would be a pain. But, using higher order functions we can write a couple of functions and re-use them.

123456789101112131415
// Function to filter on given sex
const sexFilter = (person, sex) => person.sex === sex

// Get All Males
const allMales = people.filter((person) => sexFilter(person, 'M'))

// Get All Females
const allFemales = people.filter((person) => sexFilter(person, 'F'))

// Average Function to get average age
const average = (person) =>
  person.reduce((acc, cur) => acc + cur.age, 0) / person.length

// Return oldest person
const oldest = (person) => person.sort((a, b) => b.age - a.age)[0]

With these 5 functions we can now answer all of the above questions:

12345678910
// 1. Average of everyone's age
average(people) // 32.25

// 2. Average age of each sex.
average(allMales) // 36.5
average(allFemales) // 28

// 3. Oldest of each sex
oldest(allMales) // {name: "Jon", age: 60, sex: "M"}
oldest(allFemales) // {name: "Sandra", age: 40, sex: "F"}

This is beauty of higher-order functions we can write one function and re-use it over and over again regardless of the data we feed into it or how we want to mix them together.