Polyfills for common Array methods in JavaScript
Tags: javascript, polyfill, interview, beginners
Published: 2021-07-15 19:50:24

Technical jargon alert: 
_**Polyfills**_ : A polyfill is nothing but a piece of code that implements a feature on web browsers that do not support the feature. 

Even though Array methods like **forEach, map, filter, find, reduce** exist natively in JavaScript, it is very common for interviewers to ask you to code your own implementation of these. 

I'm only gonna be covering most important ones so feel free to code your implementations of other methods as well. 

1) **forEach**
The forEach method executes a given function for each element of an array
```javascript
let arr = [1,2,3,4]
arr.forEach((item,idx,arr)=>console.log(item*2,idx))
//The console prints:
2 0 
4 1
6 2
8 3

```
Now let's implement our own version of the forEach method. 
```javascript
let myforEach = function (callback){
    //this refers to the entity that the function is a method of.
    for(let i=0;i<this.length;i++){
        callback(this[i],i,this);
    }
}

Array.prototype.myforEach=myforEach
arr.myforEach((item,idx,arr)=>console.log(item,idx,arr))
 1 0 [1, 2, 3, 4]
 2 1 [1, 2, 3, 4]
 3 2 [1, 2, 3, 4]
 4 3 [1, 2, 3, 4]
```

2) **Map**
The map() method returns a **new array** containing with the results of calling a given function on each element in the array it is called with
```javascript
let arr = [1,2,3,4]
arr.map((item)=> item*2)
//output
[2,4,6,8]
```

Let's code our own version of map!

```javascript
let myMap = function(callback){
    let result = []
    for(let i = 0;i < this.length ; i++){
        result.push(callback(this[i],i,this))
    }
    return result;
}

Array.prototype.myMap = myMap
arr.myMap((item)=>item*2) //you can include or exclude the other 2 arguments to the callback function
//output
[2,4,6,8]
```

3) **Filter**
The filter() method returns a **new array** with all elements that return true for the test implemented by the provided function.
```javascript
let arr = [1,2,3,4]
arr.filter((item)=>item%2==1)
//output
[1,3]
```

Let's now code our own implementation of filter

```javascript
let myFilter = function(callback){
    let result = [];
    for(let i=0;i<this.length;i++){
        if(callback(this[i],i,this)){
            result.push(this[i])
        }
    }
    return result;
}

Array.prototype.myFilter = myFilter
arr.filter((item,idx,arr)=>item%2==1) 
//output
[1,3]
```

4) **Find**
The find method executes the callback function once for each element of the array until the callback returns a _truthy_ value. If so, find immediately returns the value of that element. Otherwise, it returns undefined.
```javascript
let arr = [1,2,3,4]
arr.filter((item)=>item%2==1)
//output
[1,3]
```

Let's now code our own implementation of filter

```javascript
let myFilter = function(callback){
    let result = [];
    for(let i=0;i<this.length;i++){
        if(callback(this[i],i,this)){
            result.push(this[i])
        }
    }
    return result;
}

Array.prototype.myFilter = myFilter
arr.filter((item,idx,arr)=>item%2==1) 
//output
[1,3]
```

5) **Reduce**
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a _single_ output value.

The reducer function takes four arguments:

Accumulator
Current Value
Current Index
Source Array

Your reducer function's returned value is assigned to the accumulator, whose value is remembered across each iteration throughout the array, and ultimately becomes the final, single resulting value. If no initial value is provided the first element will be used as the accumulator.

```javascript
let arr = [1,2,3,4]
arr.reduce((acc,cur)=>{
    console.log("acc: " ,acc,"curr: ",cur)
    return acc+cur
})
//output
acc: 1 cur: 2
acc: 3 cur: 3
acc: 6 cur: 4
10
```

Let's now code our own implementation of filter

```javascript
function myReduce(callback, initialValue) {
  let acc,curr;

  if (!this.length && !initialValue) 
    throw new Error("Can't reduce on empty array without an intial value");
  else {
    //  If initialValue is given then it is treated as the accumulator else the 0th index is the accumulator
    acc = initialValue ? initialValue : this[0];
    for (let i = 1; i < this.length; i++) {
      curr = this[i];
      acc = callback(acc, curr, i, this);
    }
  }
  return acc;
}

Array.prototype.myReduce = myReduce
arr.myReduce((acc,cur)=>acc+cur)
//output
10
```

All the code shown above has been executed in the console, let me know incase of any error or if you want to see similar content, go ace that interview!