Creating your own bind() (Polyfill of bind)
Tags: beginners, javascript, node, tutorial
Published: 2021-05-30 06:48:50

So, what is polyfill?

Polyfill is a fallback for a method that is not supported by the browser by default. You can find browser support for any function or method on the `mdn` website.

Now, what is `bind()`?

According to `mdn`

> The `bind()` method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

This definition sounds really fancy, but what does that mean?

In simple words,

> The `bind()` takes an object as an argument and returns a new function whose `this` refers to the object we passed as an argument.

Now, we got the idea about `polyfill` and `bind()`. So, let's try to implement it.

1). let's create an object that we are going to use as a call site.

```javascript
let obj = {
  name: 'Jack',
};
```

2). Create a `function` that we need to bind with the object.

```javascript
let myFunc = function () {
  console.log(`${this.name}`);
};
```

If you call this function now, It will print `undefined`

3). Add your bind() to the function prototype.

```javascript
Function.prototype.myBind = function (obj) {
  let func = this;
  return function () {
    func.apply(obj);
  };
};
```

Putting it all together.

```javascript
let obj = {
  name: 'Jack',
};

let myFunc = function () {
  console.log(`${this.name}`);
};

Function.prototype.myBind = function (obj) {
  let func = this;
  return function () {
    func.apply(obj);
  };
};

let newFunc = myFunc.myBind(obj)
newFunc() // Jack
```

This is the basic implementation of `bind()`, But it has few edge cases. Let's say you want to pass some arguments in `myBind()`. How will you do that? Currently, we are not accepting arguments other than the object itself. Let's implement this functionality.

### The problem

```javascript
let obj = {
  name: 'Jack',
};

let myFunc = function (id) {
  console.log(`${this.name}, ${id}`);  // id will be undefined
};

Function.prototype.myBind = function (obj) {
  let func = this;
  return function () {
    func.apply(obj);
  };
};

let newFunc = myFunc.myBind(obj, 'a_random_id')
newFunc() // Jack, undefined
```

We are trying to pass `id` in `myBind` but not able to access it.

### The solution

```javascript
let obj = {
  name: 'Jack',
};

let myFunc = function (id) {
  console.log(`${this.name}, ${id}`);  // id will be undefined
};

// Accepting any number of arguments passed to myBind
Function.prototype.myBind = function (obj, ...args) {
  let func = this;
  return function () {
    func.apply(obj, [...args]);
  };
};

let newFunc = myFunc.myBind(obj, 'a_random_id')
newFunc() // Jack, a_random_id
```

Now we solved an edge case. However, there is one more improvement we can make. What if we want to pass arguments to `newFunc()`?

### The problem

```javascript
let obj = {
  name: 'Jack',
};

let myFunc = function (id, city) {
  console.log(`${this.name}, ${id}, ${city}`);  // id will be undefined
};

// Accepting any number of arguments passed to myBind
Function.prototype.myBind = function (obj, ...args) {
  let func = this;
  return function () {
    func.apply(obj, [...args]);
  };
};

let newFunc = myFunc.myBind(obj, 'a_random_id')
newFunc('New York') // Jack, a_random_id, undefined
```

We are passing 'New York' but not able to access it inside `myFunc`

### The solution

```javascript
let obj = {
  name: 'Jack',
};

let myFunc = function (id, city) {
  console.log(`${this.name}, ${id}, ${city}`);  // id will be undefined
};

// Accepting any number of arguments passed to myBind
Function.prototype.myBind = function (obj, ...args) {
  let func = this;
  // Accepting arguments passed to newFunc
  return function (...newArgs) {
    func.apply(obj, [...args, ...newArgs]);
  };
};

let newFunc = myFunc.myBind(obj, 'a_random_id')
newFunc('New York') // Jack, a_random_id, New York
```

Now I think we have covered almost all the cases. But, still, if there is anything left, Let me know in the comment section.

Time to celebrate. You have implemented your own `bind()`.

I hope this will be helpful for you.

![Bye](https://media.giphy.com/media/3o6ZtcOxQ9vi8vb9Cg/giphy.gif)