This article might be a bit long, but we'll aim to thoroughly understand and explore polyfills.
What is Polyfill?
If you web search the definition of “Polyfill“, you’ll find
A polyfill is a piece of code (usually JavaScript on the Web) used to provide modern functionality on older browsers that do not natively support it.
What does it actually mean? Let's break it down (no need for a hammer 😅); I get that it can be stressful!
Okay, imagine you’re streaming a movie, but your internet is slow. Instead of stopping, the platform lowers the resolution so you can keep watching. A polyfill works the same way in JavaScript—it provides a fallback when a browser doesn’t support a modern feature.
JavaScript evolves constantly, but older browsers don’t always support new features. For example, if you use Array.includes()
, an old browser like Internet Explorer won’t recognize it, causing errors. A polyfill is a small script that adds missing functionality, ensuring code works smoothly across all browsers.
Still in doubt?
Why is it important?
Have a look at the image below. The displayName
property displays the name of the function. Check which browsers support displayName
and which do not.
Credits to mdn documentation for the image!
displayName
is unsupported in most browsers, except for Firefox (versions 13 and 14). If used, it won’t work in Chrome, Edge, Safari, or mobile browsers, leading to errors.
Since most users rely on these browsers, developers should avoid using it or find alternative solutions like creating the polyfill of it!
I know, now you'll be eager and excited to create your own polyfill, right? Let’s do it together!
Code Your Own Polyfill: Bridging Browser Gaps 🦾
1. Array.myIncludes()
Let's help Mr. Internet Explorer (who lagged behind in exploring thing — no offense! 😬) by creating a polyfill for Array.includes()
from scratch to understand how polyfills work.
Step 1: The Problem
includes()
checks if an array contains a value. However, older browsers don’t support this method, causing errors.
const pets = ["cat", "dog", "parrot"];
console.log(pets.includes("cat")); // true
Works in modern browsers but fails in older ones! 🚫
Step 2: Creating Our Own myIncludes()
Method
We define our own method to mimic includes()
:
Array.prototype.myIncludes = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i])) {
return true;
}
}
return false;
};
How it works:
We loop through each item in the array.
The callback function checks if the item matches the condition.
If a match is found, return
true
; otherwise, returnfalse
.
Step 3: Testing the Polyfill
Now, let's use our myIncludes()
method:
const pets = ["cat", "dog", "parrot"];
const myPet = pets.myIncludes((name) => name == "cat");
console.log(myPet); // true
Even if includes()
is not available in an older browser, myIncludes()
will work as a replacement, ensuring compatibility.
2. Array.myMap()
The map()
method transforms each element of an array using a function. Here’s how we can create our own version:
if (!Array.prototype.myMap) {
Array.prototype.myMap = function (callback) {
const result = [];
for (let i = 0; i < this.length; i++) {
result.push(callback(this[i], i));
}
return result;
};
}
// Testing the polyfill
const arr = [1, 2, 3];
const doubled = arr.myMap((e) => e * 2);
console.log(doubled); // [2, 4, 6]
💡 How it works?
It loops through the array.
Applies the
callback
function to each element.Stores the result in a new array.
3. Array.myReduce()
The reduce()
method processes elements and returns a single accumulated value.
if (!Array.prototype.myReduce) {
Array.prototype.myReduce = function (callback, initialVal) {
let accumulator = initialVal;
for (let i = 0; i < this.length; i++) {
accumulator = callback(accumulator, this[i], i, this);
}
return accumulator;
};
}
// Testing the polyfill
const prices = [1, 2, 3, 4, 5];
const total = prices.myReduce((sum, val) => sum + val, 0);
console.log(`Total: Rs.${total}`); // Total: Rs.15
💡 How it works?
Starts with an
initialVal
.Loops through the array, updating
accumulator
with the callback function.Returns the final accumulated value.
Amazing these are, aren't they?
Common Polyfills Every Developer Should Know ✅
Here are some commonly used polyfills that every developer should be familiar with.
1. Object.assign()
(ES6)
Used to copy properties from one object to another.
if (!Object.assign) {
Object.assign = function (target, ...sources) {
if (target == null) {
throw new TypeError('Cannot convert undefined or null to object');
}
let to = Object(target);
sources.forEach(source => {
if (source != null) {
Object.keys(source).forEach(key => {
to[key] = source[key];
});
}
});
return to;
};
}
2. String.prototype.startsWith()
(ES6)
Checks if a string starts with a given substring.
if (!String.prototype.startsWith) {
String.prototype.startsWith = function (search, pos) {
return this.substr(pos || 0, search.length) === search;
};
}
🔹 Why it’s needed? Internet Explorer does not support startsWith()
. 🙂
3. fetch()
(ES6)
if (!window.fetch) {
console.log('Fetch API not found, loading polyfill...');
import('https://cdnjs.cloudflare.com/ajax/libs/fetch/3.6.2/fetch.min.js');
}
🔹 Why it’s needed? Many legacy browsers still rely on XMLHttpRequest
instead.
Conclusion - Polyfill it and chill!
In a nutshell, Polyfills act as a time machine, bringing modern features to older browsers and ensuring your code doesn’t throw tantrums. By mastering polyfills, you’re not just making your websites more compatible, but also leveling up as a developer!
So go ahead, write polyfills, save the web, and be the hero older browsers never knew they needed! 🚀✨