Polyfills: ‘Bind’ with and without ‘Apply’

Sadique Quraishi
The Startup
Published in
2 min readMay 6, 2020

What is polyfill?

MDN defines it as “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.”

In simple language, it is a way of adding backward compatibility.

Things to keep in mind while writing polyfill:

1. What kind of polyfill we are writing? Is it a method or Class etc…
2. What are the expected arguments of my polyfill and their order?
3. What is the return type of my polyfill?

Let see the polyfill of Bind.

Q) What kind of polyfill we are writing?
A) Method

Q) What are the expected arguments of my polyfill and their order?
A) 1st argument should be context, followed by any argument passed bu user

Q) What is the return type of my polyfill?
A) Bind returns a new method with defined context

Since bind is called with dot(.) notation on function Object, we will define our polyfill in Function’s prototype.

Bind’s polyfill using ‘Apply’ method

Function.prototype.newBindWithApply = function (ctx, ...args) {

// Preserving the current function
let fn = this;
// Preserving the default arguments passed with context
let allArguments = args;
// returning the new method with context
return function (args1) {
allArguments = [...allArguments, ...args1]
return fn.apply(ctx, allArguments)
}
}

Bind’s polyfill without using ‘Apply’ method

Function.prototype.newBindWithoutApply = function (ctx, ...args) { // Preserving the default arguments passed with context 
let allArguments = args;

/* Since we are not using call/apply, I'll create a reference of
binding method within the context, and method will be invoked
as
context.methodcall() */

ctx.fnToCall = this;
// returning the new method with context
return function (...args1) {
allArguments = [...allArguments, ...args1]
return ctx.fnToCall(...args)
}
}

Quick Implementation:

function printNameAge (argumentPassed) {
console.log(this.name, this.age, argumentPassed)
}

let p1 = printNameAge.newBindWithoutApply({name:'foo', age: 20}, 'Without Apply Default Argument')();
Output: 'foo' 20 'Without Apply Default Argument'let p2 = printNameAge.newBindWithoutApply({name:'bar', age: 40})('Without Apply Calling Argument');Output: 'bar' 40 'Without Apply Calling Argument'
let p3 = printNameAge.newBindWithApply({name:'foo', age: 20}, 'With Apply Default Argument')();Output: 'foo' 20 'With Apply Default Argument'
let p4 = printNameAge.newBindWithApply({name:'bar', age: 40})('With Apply Calling Argument');Output: 'bar' 40 'Without Apply Calling Argument'

Similarly, Quick Polyfill for Apply could be :

Function.prototype.myApply = function(ctx, ...args) {
ctx.fnToCall = this;
return ctx.fnToCall(...args)
}

These are just a quick way of writing polyfills, in a real-world scenario, one may need to to make polyfills more secure by using Object.seal() or Object.freeze().

--

--