A polyfill is a piece of code that provides modern functionality on older browsers or environments that lack support for certain features or APIs. It essentially "fills in" the gaps by emulating or replicating the behavior of the missing features.
Why do we need it?
Not all users have newer browsers; many still use older browsers that lack support for modern JavaScript features. When an application utilizing these modern features runs in these environments, it won't find the required APIs, causing the application to malfunction. To overcome this issue, we rely on the concept of Polyfills.
Let's Understand this with an example ! ! !...
Assuming we are building an e-commerce app, we store selected products in an array called myCart. Whenever a product is selected, we check if the object already exists in the 'myCart' array. If it does, we increment the count of that product; if not, we add it to the array.
Users adding a product to the cart
check if the array is empty, if it is then add the product to the cart.
If not, we utilize the 'find' method from the Array prototype to determine if the product has already been added to the cart.
If the product is found we increment the count else we push a new product into the myCart array.
In this e-commerce app, we have a class called CartService that acts as a service for handling cart-related operations. The 'myCart' array is initially empty. The CartService class includes a method called 'addProductToCart', which accepts a product as a parameter. This method performs the necessary condition checks and modifies the 'myCart' array accordingly.
The actual purpose of this blog . . . . .
The 'find' method used in the code relies on prototype inheritance of the Array and if it is not available in certain old browsers, the application may not function as expected. In such cases, the 'find' method will not be recognized or supported by the browser, potentially causing errors or unexpected behavior in the application's functionality.
To address this issue, we can develop our own implementation of the 'find' method that will be executed when the default method is not available. By doing so, our application will operate as expected in all browsers. This approach, known as a polyfill, involves creating our own implementation for existing or newly introduced JavaScript functions/methods that may not be supported in older browsers.
Let's write our 'find' method </> . . . myFind
Here we first check whether the find method is exists in the array property or not using Array.prototype.find, this will return undefined if it is not present in the current browser, then we create our own find method.
Let's break down the code line by line . . .
this === null , here this is nothing but the array which will calls the myFind method e.g. myCart.myFind(callbackFunction). we first check the array is atleast initialized if not we throw an error.
then we check whether the argument passed to the function myFind is a function using typeof predicate !== 'function' if it is not an function we thrown an error to terminate the process.
if we have the array initialized and the argument passed is an function then we first declare and initialize data that are required to implement find method
var list = object(this): the variable list will hold the current array context, so that we can use it for iteration.
var length = list.length >>> 0: this will hold the length of the list by eliminating non-negative values.
var thisArg = arguments[1]: this will have the context that is passed to myFind function when it is invoked e.g. myFind(callbackfunction,this) which is optional parameter.
now, we all set to write the core implementation of the find method
we will write an for loop to iterate the entire array and will invoke the function predicate which is to be executed with the required argumnets.
if you are not familiar with what is call please gothrough it
we invoke the predicate function with the call method which is inherited from the function prototype where,
value = list[i] which holds the currently iterated value of the array (myCart) and will pass the value as the second argument to the call method which is a required parameter of the predicate function e.g. myCart.myFind((item)=>val>10), followed by the current index i and the entire array list as an optional parameter e.g. myCart.myFind((item, index, arr)=>val>10.
if (predicate.call(thisArg, value, i, list)) if the predicate function returns true on the successful comparsion then we return the current value which is said to be the first occurrence on which the callback/predicate function returns true.
if the predicate function never returns true on any iterated value then, after all the iterations the for loop gets closed and the function defaultly returns undefined.
Its time to make our CartService to be adaptive,
How to do it ?
Just simply import the polyfill.js at the top level in CartService page
Yep!!! we are good to go, our CartService will be functional in all browser.....
Conclusion
Implementing a polyfill allows us to overcome the limitations of older browsers by providing our own implementation of JavaScript functions or methods that may not be natively supported. However, it's important to note that we don't have to build everything from scratch. There are numerous packages like Babel, Polyfill.io, core-js are available that simplify the process of polyfilling.