All Higher Order Functions Under the Hood in JavaScript
Tags: javascript, webdev, programming, testing
Published: 2022-05-20 19:42:03

## forEach - (executes a function once per array element)

```js
const forEach = (cb, array) => {
  for (let i = 0; i < array.length; i++) {
    cb(array[i], i, array)
  }
}
```
```js
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.

<hr>
## map - (returns a new array from calling a function for every array element)

```js
const map = (cb, array) => {
  const newArray = []
  for (let i = 0; i < array.length; i++) {
    newArray.push(cb(array[i], i, array))
  }
  return newArray
}
```
```js
array.map(function(currentValue, index, arr), thisValue)
```

The key difference between **map** and **forEach** is map returns a _new array_ and forEach returns _undefined_

<hr>
## filter (returns a new array filled with elements that pass a test provided by a function)

```js
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
}
```
```js
array.filter(function(currentValue, index, arr), thisValue)
```
<hr>
## some (returns _true_ on **the first element** that meets requirements; else, it will return false)

```js
const some = (cb, array) => {
  for (let i = 0; i < array.length; i++) {
    if (cb(element, index, array)) return true
  }
  return false
}
```
```js
array.some(function(currentValue, index, arr), thisValue)
```
<hr>
## every (returns _false_ on **the first element** that fails to meet requirements; else, it will return true)

```js
const every = (cb, array) => {
  for (let i = 0; i < array.length; i++) {
    if (!cb(element, index, array)) return false
  }
  return true
}
```
```js
array.every(function(currentValue, index, arr), thisValue)
```
<hr>
## reduce (method returns a single value: the function's accumulated result)

```js
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
}
```

```js
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: ```js

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: ```js

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: ```js

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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) 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😎