Any code we write, we always want it to be best and want it to work on every browser. But sometimes, our code might not work on older engines as they do on modern browsers. That's because the older engines don't understand latest features. So there's two ways we can tackle it. Use Transpilers & Polyfills.
Transpilers/Transcompilers are piece of software which can translates source code in modern/non-Javascript languages to javascript source code. Some examples are babel & traceur compilers for JS
What are Polyfills and origins:
Poly: Solved by any number of ways.
Fill: Can fill the holes in old browsers wherever needed with technology.
Polyfill/polyfiller is a piece of code/plugin used to provide functionalities on older browsers that do not natively support it or browsers which may implement same features in different ways.
Why not use these polyfills exclusively then? For better functionality and performance. Native implementations of APIs can do more and are faster than polyfills. And also not to reinvent the wheel.
What Libraries can I use for filling these holes:
Core js - includes needed features
polyfill.io - provides script with polyfills.
Where can I find browser support/compatibility details for different features:
- https://kangax.github.io/compat-table/es6/ – for pure JavaScript. https://caniuse.com/ – for browser-related functions
Let's see how some of the functions we use extensively work under the hood!
1. call()
Function:
call(thisArg, ...args)
Usage:
fn.call(currentContext, arg1, arg2, argN)
Description: Does function borrowing ie; Borrow functions from other objects and use that data on other objects
Polyfill: Call
Function.prototype.customCall = function (currentThis = {}, ...args) {
// check if current context is pointing to a function
if (typeof this !== 'function') {
throw new Error(this + 'cannot call')
}
currentThis.fnName = this;
currentThis.fnName(...args);
};
2. apply()
Function:
apply(thisArg = {}, ...args = [])
Usage:
fn.call(currentContext, [arg1, arg2, argN])
Description: Just like call, does function borrowing but the arguments are passed as an array
Polyfill:Apply
Function.prototype.customApply = function (currentThis = {}, args = []) {
// check if provided arguments is an array
if (!Array.isArray(args)) {
throw new Error(this + 'Invalid argument type')
}
// check if current context is pointing to a function
if (typeof this !== 'function') {
throw new Error(this + 'cannot call')
}
currentThis.fnName = this;
currentThis.fnName(...args);
};
3. bind()
Function:
bind(thisArg = {}, ...args = [])
Usage:
fn.bind(currentContext, [arg1, arg2, argN])
Description: Returns a new function with new "this" context.
Polyfill: Bind
Function.prototype.customBind = function (...args) {
const currContext = this;
// Get all arguments except 1st as 1st is context
let params = args.slice(1);
//Bind returns copy of the function & can have new args passed to the invoking function
return function (...arguments) {
//args[0] is the new context and new arguments provided while binding and invoking
currContext.apply(args[0], [...params, ...arguments]);
};
}
Stay tuned for Part 2 Keep learning!