Enhancing Your JavaScript Skills: A Look at Polyfills

Enhancing Your JavaScript Skills: A Look at Polyfills

·

7 min read

In today's rapidly evolving technological landscape, browsers require frequent updates to support new technologies. Without these updates, many recent advancements might not function properly. However, this issue often goes unnoticed due to the use of Polyfills. Let's delve into what Polyfills are, why they are essential, and how you can create your own.

What is Polyfill? - Understanding the Basics of Polyfills

According to mdn web docs :

A polyfill is a piece of code (usually JavaScript on web) used to provide modern functionality on older browsers that do not natively support it.

Why we need Polyfills? - The Importance of Polyfills in Modern Web Development

We need polyfills for two important reasons.

  1. New Features : Polyfills enable programmers to use cutting edge functions in older version of browser natively that does not support these functions.

  2. Browser Compatibility : The latest features of programming languages or web platforms might not be supported by all browsers and environments, leading to compatibility issues for developers. Polyfills help make sure that the code works properly even in older versions of browsers.

Implementing Polyfills in JavaScript - Crafting Your Own JavaScript Polyfills

Lets make our own polyfills in JavaScript. To make our own polyfills we need to consider some basic and important points before making the polyfills.

  • What the function will it return?

  • what input does that function take?

Now that you know the important points, lets code some polyfills.

Polyfill for map() method :

The map() method of Array instances creates a new array populated with the results of calling a provided function on every element in the calling array.

Syntax :

map(callbackfn)
map(callbackfn, thisArg)

Parameters :

callbackfn

A function to execute for each element in array. Its return value is added to the new array as a single element. The function is called which following arguments :

  • element : The current element being processed in the array.

  • index : The index of current element.

  • array : The array on which map() function is called upon.

thisArg optional

A value to use as this when executing the callbackfn.

Return Value :

A new array with each element being the result of the callback function.

Example of map() method :

const num = [1,2,3,4,5]

const array = num.map( (n) => n*2 )
// output : [2,4,6,8,10]

Polyfill :

if (!Array.prototype.myMap()) {
    Array.prototype.myMap = function(callbackfn) {
        const result = []
        const originalArray = this
        for (let i = 0; i < originalArray.length; i++) {
            const element = callbackfn(originalArray[i], i)
            result.push(element)
        }
        return result
    }
}

Testing Polyfill :

const num = [1,2,3,4,5]
const newNum = num.myMap( (num) => num*num )
// output : [1,4,9,16,25]

Dry Run :

Iterationnum (current element)operation (num*num)New Array (result)
1st11×1 = 1[1]
2nd22×2 = 4[1, 4]
3rd33×3 = 9[1, 4, 9]
4th44×4 = 16[1, 4, 9, 16]
5th55×5 = 25[1, 4, 9, 16, 25]

This is all about the polyfill of map().

Polyfill of forEach() method :

The forEach() method of Array instances executes a provided function once for each array element.

Syntax :

forEach(callbackFn)
forEach(callbackFn, thisArg)

Parameters :

callbackfn

A function to execute for each element in array. Its return value is discarded. The function is called which following arguments :

  • element : The current element being processed in the array.

  • index : The index of current element.

  • array : The array on which map() function is called upon.

thisArg optional

A value to use as this when executing the callbackfn.

Return Value :

None undefined

Example of forEach() method :

const fruits = ["apple", "mango", "pineapple"]

fruits.forEach( fruit => console.log(fruit) )
// output : ["apple", "mango", "pineapple"]

Polyfill :

if (!Array.prototype.myForEach()) {
    Array.prototype.myForEach = function(callbackfn) {
        const originalArray = this
        for (let i = 0; i < originalArray.length; i++) {
            callbackfn(this[i])
        }
    }
}

Testing Polyfill :

const numbers = [10, 20, 30, 40, 50];

numbers.myForEach((num, index) => {
    console.log(`Index: ${index}, Value: ${num}, Double: ${num * 2}`);
});

Dry Run :

Iterationindexnum (current element)Operation (num * 2)Console Output
1st01010 × 2 = 20Index: 0, Value: 10, Double: 20
2nd12020 × 2 = 40Index: 1, Value: 20, Double: 40
3rd23030 × 2 = 60Index: 2, Value: 30, Double: 60
4th34040 × 2 = 80Index: 3, Value: 40, Double: 80
5th45050 × 2 = 100Index: 4, Value: 50, Double: 100

Polyfill of reduce() method :

The reduce() method of Array instances executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.

Syntax :

reduce(callbackFn)
reduce(callbackFn, initialValue)

Parameters :

callbackfn

A function to execute for each element in the array. Its return value becomes the value of the accumulator parameter on the next invocation of callbackfn. For the last invocation, the return value becomes the return value of reduce(). The function is called with the following arguments:

  • accumulator : The value resulting from the previous call to callbackfn. On the first call, its value is initialValue if the latter is specified; otherwise is array[0].

  • currentValue : The value of the current element. On the first call, its value is array[0] if initialValue is specified; otherwise its value is array[1].

  • currentIndex : The index position of currentValue in the array. On the first call, its value is 0 if initialValue is specified, otherwise 1.

  • array : The array reduce() was called upon.

initialValue optional

A value to which accumulator is initialized the first time the callback is called. If initialValue is specified, callbackFn starts executing with the first value in the array as currentValue. If initialValue is not specified, accumulator is initialized to the first value in the array, and callbackFn starts executing with the second value in the array as currentValue. In this case, if the array is empty (so that there's no first value to return as accumulator), an error is thrown.

Return Value :

The value that results from running the "reducer" callback function to completion over the entire array.

Example of reduce() method :

const num = [1,2,3,4,5]

const sum = num.reduce( (accumulator, currentValue) => accumulator + currentValue )
// output : 15

Polyfill :

if (!Array.prototype.myReduce()) {
    Array.prototype.myReduce = function(callbackfn) {
        const result = 0;
        const originalArray = this
        for (let i = 0; i < originalArray.length; i++) {
            result = callbackfn(result, originalArray[i])
        }
    }
    return result;
}

Testing Polyfill :

const num = [1,2,3,4,5]
const sum = num.myReduce( (accumulator, currentValue) => accumulator + currentValue )
// output : 15

Dry Run :

Iteratoraccumulator (initial Value = 0 )currentValue (array element)Operation (accumulator + currentValue)New accumulator
1st010 + 11
2nd121 + 23
3rd333 + 36
4th646 + 410
5th10510 + 515

Conclusion

Polyfills play a crucial role in modern web development by bridging the gap between new technologies and older browser versions. They allow developers to implement cutting-edge features while ensuring compatibility across different environments. By understanding and creating polyfills, developers can enhance their JavaScript skills and ensure their applications are accessible to a wider audience. Whether it's the map(), forEach(), or reduce() methods, implementing polyfills helps maintain functionality and user experience, regardless of the browser being used. Embracing polyfills is a step towards more robust and future-proof web applications.