Array Methods Polyfills

·

5 min read

Polyfills

Polyfills are a kind of browser fallback function that are used in case any of the browser functions stops working or is not supported in that browser then developers need to write their own functions for that browser.

Today we are going to write polyfills for some common array methods which we use everyday.

Polyfill for map()

The map() method takes three arguments current element, index, and the array it was called with and returns us the new array according to the condition in the callback function defined. You can read more about it here.

Array.prototype.myMap = function (callback) {
    var ansArr = [];

    // Iterating over every element of given array and making new array
    for (var i = 0; i < this.length; i++) {
        ansArr.push(callback(this[i], i, this));
    }
    return ansArr;
}

Polyfill for find()

The find() method takes three arguments current element, index, and the array it was called with and returns us the first element which returns true for the condition in the callback function. You can read more about it here.

Array.prototype.myFind = function (callback) {

    // Iterating over every element of given array
    for (var i = 0; i < this.length; i++) {
        const indexAns = callback(this[i], i, this);

        // Return the element when the condition satisfies
        if (indexAns)
            return this[i];
    }
    return undefined;
}

Polyfill for filter()

The filter() method takes three arguments current element, index, and the array it was called with and returns us the array of elements which returns true for the condition in the callback function. You can read more about it here.

Array.prototype.myFilter = function (callback) {
    var ansArr = [];

    // Iterating over every element of given array
    for (var i = 0; i < this.length; i++) {
        const indexAns = callback(this[i], i, this);

        // Pushing the element into new array if it returns true
        if (indexAns) {
            ansArr.push(this[i]);
        }
    }
    return ansArr;
}

Polyfill for flat()

The flat() method takes one argument specifying to which depth the array should be flattened whose default value is 1. It returns a new array with the sub-array elements concatenated into it. You can read more about it here.

Array.prototype.myFlat = function (depth = 1) {  // Default value of depth which is 1
    var ansArr = [];

    // Iterating over every element of given array
    for (var i = 0; i < this.length; i++) {

        // Pushing the element when depth is zero
        if (depth === 0) {
            ansArr.push(this[i]);  
        }
        else {

            // Calling the myFlat() function again if the given value is an array
            if (typeof this[i] === "object") {      
                const ans = this[i].myFlat(depth - 1);   
                ansArr = ansArr.concat(ans);
            }

            //Pushing the element if it is a single value
            else {
                ansArr.push(this[i]); 
            }
        }
    }
    return ansArr;
}

Polyfill for reduce()

The reduce() method takes four arguments previousValue, currentValue, currentIndex and the array it was called with and returns us a value resultant of the callback function on every element of the array. You can read more about it here.

Array.prototype.myReduce = function (callback, inititalValue) {

    // Default value of accumulator(undefined if initialValue is not provided)
    var accumulator = inititalValue;  

    // Iterating over every element of given array
    for (var i = 0; i < this.length; i++) {

        // Check if accumulator has any value otherwise just give the currentValue to the accumulator
        if (accumulator) {
            accumulator = callback(accumulator, this[i], i, this);
        }
        else {
            accumulator = this[i];
        }
    }
    return accumulator;
}

Polyfill for slice()

The slice() method takes two arguments start whose default value is 0 and end whose default value is length of the array it was called with and returns a new array from start to end index of the array (end not included). You can read more about it here.

Array.prototype.mySlice = function (startIndex = 0, endIndex = this.length) {
    var ansArr = [];

    // If startIndex is greater than length of array then return empty array
    if (startIndex > this.length) {
        return ansArr;
    }

    // If startIndex is less than zero then calculate startIndex from end of array
    if (startIndex < 0) {
        startIndex = endIndex + startIndex;  
    }

    // If endIndex is greater than length of array then assign it with length of array
    if (endIndex > this.length) {
        endIndex = this.length;   
    }

    // If endIndex is less than zero then calculate endIndex from end of array
    else if (endIndex < 0) {
        endIndex = this.length + endIndex;   
    }

   // Copy elements from startIndex to endIndex of the array to new array
    for (let i = startIndex; i < endIndex; i++) {
        ansArr.push(this[i]);
    }
    return ansArr;
}

Polyfill for splice()

The splice() method takes three arguments start, deleteCount and item1, item2, .... It mutates the given array by deleting the number of elements specified from the start and replacing them with new elements mentioned. You can read more about it here.

Array.prototype.mySplice = function () {
    var startIndex = arguments[0];
    var deleteCount = arguments[1];
    var endIndex = startIndex + deleteCount - 1;

    // If start is greater than length of array then assign it to length of array
    if (startIndex > this.length) {
        startIndex = this.length;
    }

    // If start is equal to -Infinity then assign it to zero
    else if (startIndex === -Infinity) {
        startIndex = 0;
    }

    // If startIndex is less than zero then calculate startIndex from end of array
    else if (startIndex < 0) {
        startIndex = this.length + startIndex;
    }

    var itemsBeforeSplice = [];
    var itemsAfterSplice = [];

   // Iterating over elements of array
    for (let i = 0; i < this.length; i++) {

        // Copy elements between startIndex and endIndex
        if (i < startIndex) {
            itemsBeforeSplice.push(this[i]);
        }

        // Copy elements after endIndex
        else if (i > endIndex) {
            itemsAfterSplice.push(this[i]);
        }
    }

   // Add new elements that needs to be added to the array
    for (let i = 2; i < arguments.length; i++) {
        itemsBeforeSplice.push(arguments[i]);
    }

    // Concatinate elements after endIndex 
    itemsBeforeSplice = itemsBeforeSplice.concat(itemsAfterSplice);

    // Copy elements in the original array
    for (let i = 0; i < itemsBeforeSplice.length; i++) {
        this[i] = itemsBeforeSplice[i];
    }

    // If deleteCount is greater then the size of return array, then just return empty array.
    if (deleteCount > this.length - startIndex) {
        this.length = 0;
    }
}

I hope this blog made you understand polyfills for some common array methods and you go on and make polyfills for other methods as well.

You can connect with me on LinkedIn and Twitter.