# Writing polyfill of reduce method present on Array in JavaScript

### Introduction

JavaScript is a versatile programming language that provides developers with a rich set of built-in methods to manipulate arrays. One such method is `reduce()`, which allows you to perform powerful operations on arrays by reducing them to a single value. In this article, we will explore the concept of `reduce()`, its benefits, and learn how to write our own polyfill for the `reduce()` method.

### Understanding Array.reduce():

The `reduce()` method is used to **iterate over an array and accumulate a single value** by applying a provided function to each element.

*It takes two parameters: a callback function and an optional initial value*. *The callback function receives 4 arguments: an accumulator (the value accumulated so far), the current element being processed, the current index from the array & the entire array.*

The callback function can perform any operation on the elements and modify the accumulator as needed. The `reduce()` method returns the final accumulated value.

### Benefits of using Array.reduce():

The `reduce()` method offers several advantages that make it a powerful tool for array manipulation:

1. Summarizing Data: `reduce()` allows you to calculate a single value based on the elements of an array. For example, you can easily find the sum, product, or average of an array of numbers using the `reduce()` method.
    
2. Transforming Data: By providing a transformation function, you can use `reduce()` to convert an array into a different data structure or format. This is particularly useful when dealing with complex data manipulations or aggregations.
    
3. Filtering Data: `reduce()` can be used to filter out specific elements from an array based on a condition. You can accumulate only the desired elements by applying filtering logic within the callback function.
    
4. Performing Complex Operations: With `reduce()`, you can perform more complex operations such as finding the maximum or minimum value, concatenating strings, or even building entirely new arrays.
    

Now, that you know what is reduce method & its usage. Let's get started with writing the polyfill for reduce method.

### Polyfill for Array.prototype.reduce

Let me first show you the entire code, then we will go step by step understanding bits and pieces of it.

```javascript
Array.prototype.myReduce = function (callbackFn, initialValue) {
  if (this.length === 0 && initialValue === undefined) {
    throw new TypeError("cant perform reduce of an empty array with no initial value");
  }

  if (initialValue === undefined) {
    initialValue = this[0];
  }

  let acc = initialValue;

  let i = 0;
  if (arguments.length < 2) {
    // meaning: if there is no initial value, the 1st index of array is taken in acc, so we will be iterating from 2nd.
    i = 1;
  }

  // callback function takes, (acc, curr, index, array)
  for (; i < this.length; i++) {
    acc = callbackFn(acc, this[i], i, this);
  }

  return acc;
};
```

We are adding the function to `Array.prototype` so that we can directly use it on arrays with the dot notation and with the name `myReduce`.

**Looking for Edge cases:**

In the `reduce` implementation, we notice that, if we provide an empty array length & with no initial value, we get a TypeError with the message as presented below

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683523345243/c4518eaf-5b9f-41c0-b3c6-cf99dd7b4268.png align="center")

Hence, we are adding our first check

```javascript
if (this.length === 0 && initialValue === undefined) {
    throw new TypeError("cant perform reduce of an empty array with no initial value");
  }
```

Next, we are checking if the user has provided the `initialValue` or not. Based on the definition of reduce from [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) we know that if there is not `initialValue` defined, then we pass on the 1st index of the array.

And that is why we add this check

```javascript
if (initialValue === undefined) {
    initialValue = this[0];
}
```

Now, from the definition, we know that the accumulator is the total value so far & in the 1st iteration, it will be equivalent to the 1st index of the array element.

We also perform a check,

```javascript
let i = 0;
if (arguments.length < 2) {
  i = 1;
}
```

This is to know that if we had got an `initialValue` at the start, if not, then we are assigning `i=1` which means the iteration will start from `1` simply because now `acc` has the 1st index of the array.  
If not, the iteration will start from `0` with the `initialValue` provided by the user.

Next, we have a simple for loop which iterates over the array and calls the callback function & thus returning the `acc` aka accumulator.

```javascript
for (; i < this.length; i++) {
  acc = callbackFn(acc, this[i], i, this);
}
return acc;
```

  
Combine all of these steps, and you get 👇

```javascript
Array.prototype.myReduce = function (callbackFn, initialValue) {
  if (this.length === 0 && initialValue === undefined) {
    throw new TypeError("cant perform reduce of an empty array with no initial value");
  }

  if (initialValue === undefined) {
    initialValue = this[0];
  }

  let acc = initialValue;

  let i = 0;
  if (arguments.length < 2) {
    i = 1;
  }

  for (; i < this.length; i++) {
    acc = callbackFn(acc, this[i], i, this);
  }

  return acc;
};
```

That's it, folks.  
I hope this was useful and made the `reduce` method more clear now.

I have also written other polyfills & I am maintaining this [repository on github](https://github.com/akshayraichur/js-polyfills), check it out & give it a star.

Thank you!
