Problem

Enhance all functions to have the bindPolyfill method. When bindPolyfill is called with a passed object obj, that object becomes the this context for the function.

For example, if you had the code:

1
2
3
4
function f() {
  console.log('My context is ' + this.ctx);
}
f();

The output would be "My context is undefined". However, if you bound the function:

1
2
3
4
5
function f() {
  console.log('My context is ' + this.ctx);
}
const boundFunc = f.boundPolyfill({ "ctx": "My Object" })
boundFunc();

The output should be "My context is My Object".

You may assume that a single non-null object will be passed to the bindPolyfill method.

Please solve it without the built-in Function.bind method.

Examples

Example 1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Input: 
fn = function f(multiplier) { 
  return this.x * multiplier; 
}
obj = {"x": 10}
inputs = [5]
Output: 50
Explanation:
const boundFunc = f.bindPolyfill({"x": 10});
boundFunc(5); // 50
A multiplier of 5 is passed as a parameter.
The context is set to {"x": 10}.
Multiplying those two numbers yields 50.

Example 2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Input: 
fn = function speak() { 
  return "My name is " + this.name; 
}
obj = {"name": "Kathy"}
inputs = []
Output: "My name is Kathy"
Explanation:
const boundFunc = f.bindPolyfill({"name": "Kathy"});
boundFunc(); // "My name is Kathy"

Constraints:

  • obj is a non-null object
  • 0 <= inputs.length <= 100

Can you solve it without using any built-in methods?

Solution

Method 1 – Polyfill Using Closure

Intuition

We can add a method to Function.prototype that returns a new function. When called, this new function invokes the original function with the provided object as this using Function.prototype.apply.

Approach

  • Define Function.prototype.bindPolyfill as a function that takes an object and returns a new function.
  • The returned function, when called, invokes the original function with the given object as this and passes along any arguments.
  • Do not use the built-in Function.prototype.bind.

Code

1
2
3
4
5
6
Function.prototype.bindPolyfill = function(obj) {
  const fn = this;
  return function(...args) {
    return fn.apply(obj, args);
  };
};

Complexity

  • ⏰ Time complexity: O(1) (binding is constant time)
  • 🧺 Space complexity: O(1)