Mastering JavaScript Polyfills: A Comprehensive Overview

Table of contents
- Steps to write Polyfill
- Array.push() | Array.myPush()
- Array.pop() | Array.myPop()
- Array.unshift() | Array.myUnshift()
- Array.shift() | Array.myShift()
- Array.map() | Array.myMap()
- Array.filter() | Array.myFilter()
- Array.some() | Array.mySome()
- Array.reduce() | Array.myReduce()
- Array.every() | Array.myEvery()
- Array.find() | Array.myFind()
- Array.findIndex() | Array.myFindIndex()
- Array.fill() | Array.myFill()
- Array.splice() | Array.mySplice()

Have you ever wondered ? like while writing code for website how does browser know about the .map() .filter() etc
Well it’s because of prototype described in all of the browser but what if someone is using a browser that does not supports any of those like it is returning Error arr.map() is not a function
What will you do ? well I will try to write my own .map function !
So as we already discussed about what is poly fill and prototype let’s go and write our own polyfills
Steps to write Polyfill
Understand what you have to create : I mean if don’t know what map function does then how can you write alternative for it . so first of all study about the method
start creating it and try to use old javascript : you know browser is old and not supporting .map() may also be not supporting .push() so let’s use simple for loop for creating our polyfill
Array.push() | Array.myPush()
Characteristic of .push()
method
It takes an element as argument
appends the array for which it is called with the provided value
overrides original array
returns updated length
time complexity : O(1)
if (!Array.prototype.myPush) {
Array.prototype.myPush = function (val) {
this[this.length] = val;
return this.length;
};
}
Array.pop() | Array.myPop()
Characteristic of .pop()
method
It does not takes any argument
removes last element from array
overrides original array
returns element which is being removed
time complexity : O(1)
if (!Array.prototype.myPop) {
Array.prototype.myPop = function () {
let lastVal = this[this.length - 1];
this.length -= 1;
return lastVal;
};
}
Array.unshift() | Array.myUnshift()
Characteristic of .unshift()
method
It takes on element as argument
It increases arr size → shift all elements to right by 1 space
places argument val at 0th index
overrides original array
returns updated array size
time complexity : O(n)
if (!Array.prototype.myUnshift) {
Array.prototype.myUnshift = function (val) {
let newSize = this.length + 1;
for (let i = newSize - 1; i > 0; i--) {
this[i] = this[i - 1];
}
this[0] = val;
return this.length;
};
}
Array.shift() | Array.myShift()
Characteristic of .shift()
method
does not takes any argument
starting from index 1 shifts all elements to left
decreases arr length
overrides original array
returns removed elements
time complexity : O(n)
if (!Array.prototype.myShift) {
Array.prototype.myShift = function () {
let firstElem = this[0];
for (let i = 0; i < this.length - 1; i++) {
this[i] = this[i + 1];
}
this.length--;
return firstElem;
};
}
Array.map() | Array.myMap()
Characteristic of .map()
method
Takes a callback function as argument
- Callback function must return a value
starting from index 0 runs callback function on all elements
does not overrides original array
returns new array after applying the function
time complexity : O(n)
if (!Array.prototype.myMap) {
Array.prototype.myMap = function (userFn) {
if (typeof userFn !== "function") {
throw new Error(
`For myFilter got ${typeof userFn} but Expected a Function as argument`
);
}
const newArray = new Array(this.length); // Preallocate space
for (let i = 0; i < this.length; i++) {
newArray[i] = userFn(this[i], i);
}
return newArray;
};
}
Array.filter() | Array.myFilter()
Characteristic of .filter()
method
Takes a callback function as argument
- callback function must return a value
starting from index 0 runs callback function on all elements
- for which callback function returns true
valid values are then pushed into empty array
does not overrides original array
returns new array after applying the function
time complexity : O(n)
if (!Array.prototype.myFilter) {
Array.prototype.myFilter = function (userFn) {
if (typeof userFn !== "function") {
throw new Error(
`For myFilter got ${typeof userFn} but Expected a Function as argument`
);
}
let newArr = [];
for (let i = 0; i < this.length; i++) {
if (userFn(this[i], i)) {
newArr.myPush(this[i]);
}
}
return newArr;
};
}
Array.some() | Array.mySome()
Characteristic of .some()
method
Takes a callback function as argument
- callback function must return a value
starting from index 0 runs callback function on all elements
- Finds a element for which callback function returns true
true is returned when function returns true even for one element
- else false is returned
does not overrides original array
time complexity : O(n)
if (!Array.prototype.mySome) {
Array.prototype.mySome = function (userFunc) {
if (typeof userFunc !== "function") {
throw new Error(`Received ${typeof userFunc} ,expected 'function`);
}
for (let i = 0; i < this.length; i++) {
if (userFunc(this[i], i)) return true;
}
return false;
};
}
Array.reduce() | Array.myReduce()
Characteristic of .reduce()
method
Takes a callback function as argument along with an initial value
starting from index 0 runs callback function on all elements
- applies callback function and then update the accumulated value
returns final accumulated value
does not overrides original array
time complexity : O(n)
if (!Array.prototype.myReduce) {
Array.prototype.myReduce = function (userFunc, initialVal = 0) {
if (typeof userFunc !== "function") {
throw new Error(`Received ${typeof userFunc} ,expected 'function`);
}
let accumulatedResult = initialVal;
for (let i = 0; i < this.length; i++) {
accumulatedResult = userFunc(accumulatedResult, this[i], i);
}
return accumulatedResult;
};
}
Array.every() | Array.myEvery()
Characteristic of .every()
method
Takes a callback function as argument
- callback function must return a value
starting from index 0 runs callback function on all elements
- Finds a element for which callback function returns false
false is returned when function returns false even for one element
- else true is returned
does not overrides original array
time complexity : O(n)
if (!Array.prototype.myEvery) {
Array.prototype.myEvery = function (userFunc) {
if (typeof userFunc !== "function") {
throw new Error(`Received ${typeof userFunc} ,expected 'function`);
}
for (let i = 0; i < this.length; i++) {
if (!userFunc(this[i], i)) {
return false;
}
}
return true;
};
}
Array.find() | Array.myFind()
Characteristic of .find()
method
Takes a callback function as argument
- callback function must return a value
starting from index 0 runs callback function on all elements
- Finds a element for which callback function returns true
value of
first element
is returned for which callback function returned true- else if no element found
undefined
is returned
- else if no element found
does not overrides original array
time complexity : O(n)
if (!Array.prototype.myFind) {
Array.prototype.myFind = function (userFunc) {
if (typeof userFunc !== "function") {
throw new Error(`Received ${typeof userFunc} ,expected 'function`);
}
for (let i = 0; i < this.length; i++) {
if (userFunc(this[i], i)) {
return this[i];
}
}
return undefined;
};
}
Array.findIndex() | Array.myFindIndex()
Characteristic of .findIndex()
method
Takes a callback function as argument
- callback function must return a value
starting from index 0 runs callback function on all elements
- Finds a element for which callback function returns true
index of first element
is returned for which callback function returned true- else if no element found
-1
is returned
- else if no element found
does not overrides original array
time complexity : O(n)
if (!Array.prototype.myFindIndex) {
Array.prototype.myFindIndex = function (userFunc) {
if (typeof userFunc !== "function") {
throw new Error(`Received ${typeof userFunc} ,expected 'function`);
}
for (let i = 0; i < this.length; i++) {
if (userFunc(this[i], i)) {
return i;
}
}
return undefined;
};
}
Array.fill() | Array.myFill()
Characteristic of .fill()
method
Takes a variable* as argument also may take start and end indexes
starting from index
start
runs for loop tillend
index- replaces all the elements between this range with value of variable passed
updated arr is returned
does not overrides original array
time complexity : O(n)
if (!Array.prototype.myFill) {
Array.prototype.myFill = function (val, start = 0, end = this.length - 1) {
let newArr = JSON.parse(JSON.stringify(this));
for (let i = start; i <= end; i++) {
newArr[i] = val;
}
return newArr;
};
}
Array.splice() | Array.mySplice()
Characteristic of .splice()
method
Takes a start index as argument also may take delete count and …items to be inserted
from index 0 to startIndex-1 all elements are kept as it is
elements from start index are deleted till delete count full fills
now …items are inserted at start index
- after inserting all …items other elements of main array is kept as it is at end of updated array
overrides original array
time complexity : O(n)
if (!Array.prototype.mySplice) {
Array.prototype.mySplice = function (
startIndex,
deleteCnt = this.length,
...items
) {
let newArr = [];
for (let i = 0; i < startIndex; i++) {
newArr.push(this[i]);
}
newArr.push(...items);
for (let i = startIndex + deleteCnt; i < this.length; i++) {
newArr.push(this[i]);
}
this.length = 0;
for (let i = 0; i < newArr.length; i++) {
this.push(newArr[i]);
}
};
}
Hooray ! just wrote multiple polyfills for various array prototype so now you are in better place and you can write similar polyfills for object,string or any other datatype
if there is a predefined method
you can write it’s polyfill to make sure that you website runs on every platform
Just remember
Analyse Characteristic of method for which going to write polyfill
now write the polyfill
Subscribe to my newsletter
Read articles from Vineet Raj directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by