All Higher Order Functions Under the Hood in JavaScript
Gabriel Pedroza
Posted on May 20, 2022
forEach - (executes a function once per array element)
const forEach = (cb, array) => {
for (let i = 0; i < array.length; i++) {
cb(array[i], i, array)
}
}
array.forEach(function(currentValue, index, arr), thisValue)
Iterating through an array declaratively using a callback function to manipulate the array respectively. Second param is undefined by default and when a value is passed to the function, it gets the this value. This is usually never used though.
map - (returns a new array from calling a function for every array element)
const map = (cb, array) => {
const newArray = []
for (let i = 0; i < array.length; i++) {
newArray.push(cb(array[i], i, array))
}
return newArray
}
array.map(function(currentValue, index, arr), thisValue)
The key difference between map and forEach is map returns a new array and forEach returns undefined
filter (returns a new array filled with elements that pass a test provided by a function)
const filter = (cb, array) => {
const newArray = []
for (let i = 0; i < array.length; i++) {
const element = array[i]
if (cb(element, i, array)) newArray.push(element)
}
return newArray
}
array.filter(function(currentValue, index, arr), thisValue)
some (returns true on the first element that meets requirements; else, it will return false)
const some = (cb, array) => {
for (let i = 0; i < array.length; i++) {
if (cb(element, index, array)) return true
}
return false
}
array.some(function(currentValue, index, arr), thisValue)
every (returns false on the first element that fails to meet requirements; else, it will return true)
const every = (cb, array) => {
for (let i = 0; i < array.length; i++) {
if (!cb(element, index, array)) return false
}
return true
}
array.every(function(currentValue, index, arr), thisValue)
reduce (method returns a single value: the function's accumulated result)
function reduce(array, cb, initialValue) {
let i = 1
let currentValue = array[0]
if (arguments.length > 2) {
currentValue = initialValue
i = 0
}
for (; i < array.length; i++) { // i has already been created, hence the lonely semi colon
currentValue = cb(currentValue, array[i], i, array)
}
return currentValue
}
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
Very weird-looking under the hood but all it really does is it reduces what was passed into one value. It can be a number, array, object, etc... If the second argument is not passed, it will begin at the first index of the array; else, it will start at whatever you passed it. For example:
let sum = [0, 1, 2, 3].reduce(function (previousValue, currentValue) {
return previousValue + currentValue
}, 0)
// sum is 6
It takes the initial value that was passed, 0, and adds the first index. In this case, you would not need to pass the initialValue since you are just adding numbers and it will save you one operation. Another example using an object would be:
const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
let countedNames = names.reduce(function (allNames, name) {
if (name in allNames) {
allNames[name]++
}
else {
allNames[name] = 1
}
return allNames
}, {})
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
This example will iterate through the array and check if the name already exists as a key in the object (the initial value is an empty object where you will store the result). If it already has created the name, it will add one more to it. One last example to truly make sure this is understood is:
const numbers = [-5, 6, 2, 0,];
const doubledPositiveNumbers = numbers.reduce((previousValue, currentValue) => {
if (currentValue > 0) {
const doubled = currentValue * 2;
previousValue.push(doubled);
}
return previousValue;
}, []);
console.log(doubledPositiveNumbers); // [12, 4]
This combines filter and map higher-order functions into a single reduce method which is a lot more efficient than traversing through the array twice. There is another hof called reduceRight and it does the exact same thing but traverses from right to left instead.
There are a lot of examples that go into reduce in the mdn so I'd recommend you check it out if you want to see the more complex examples. I hope this was helpful because not only this took time but also makes me appreciate the built-in methods by JavaScript. Don't forget to bookmark this because I know I will😎
Posted on May 20, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
December 30, 2022