Use bind with caution

Ujjwal Gupta
4 min readApr 2, 2021

If you are a javascript developer, you must have been using or heard of three methods -

  1. bind
  2. call
  3. apply

Well if you have not: let me give you summary of these methods -

bind, call & apply are used to set the context of a method at run time.

For more description, take a look at this article - https://medium.com/@leonardobrunolima/javascript-tips-apply-vs-call-vs-bind-d738a9e8b4e1

In this article - i will talk only about bind and why to use with caution.

bind creates a new method which have supplied context.

e.g -

function fullName() {
return this.firstName + ' ' + this.lastName;
}

if you will call this method, output will be “undefined undefined”

this is because value of “this” in method is by default “window”. Let’s correct this method to return a valid value by using bind.

function fullName() {
return this.firstName + ' ' + this.lastName;
}
var user = {
firstName: 'ujjwal',
lastName: 'gupta'
}
var fullNameWithContext = fullName.bind(user);fullNameWithContext();

In the above method we have created a new method “fullNameWithContext” using bind supplying value “user”, so value of “this” will be “user” inside method “fullNameWithContext”.

So now output is “ujjwal gupta”.

Well, this solves the problem and return a valid output.

Let’s see another real life problem where we have below requirements -

  1. There is a button Submit, which will submit data to server on click
  2. After data is submitted, we need to remove submit button and show a good user friendly message.

Requirement - 1

Consider our html code is

<div id="divContainer">
<button id="btnSubmit">Submit</button>
</div>

For simplicity (generally data would be collected from html form), consider our data is stored inside a variable like this -

var user = {
firstName: 'ujjwal',
lastName: 'gupta',
gender: 'male',
address: "Bengaluru india"
}

Now, let’s register “click” event on submit button.

function submitData() {
fetch("url", {
data: {
name: this.firstName + ' ' + this.lastName,
gender: this.gender,
address: this.address,
isNewuser: true
}
})
}
var el = document.querySelector('#btnSubmit');
el.addEventListener('click', submitData.bind(user));

In the above method, we have register event “click” with event listener created using bind .

First requirement is completed. Let’s solve our next requirement -

Requirement 2

Let’s remove the button

function submitData() {
fetch("url", {
data: {
name: this.firstName + ' ' + this.lastName,
gender: this.gender,
address: this.address,
isNewuser: true
}
}).then(_ => {
var el = document.querySelector('#btnSubmit');
var container = document.querySelector('#divContainer');
// remove button from dom
container.removeChild(el);
// remove event registered
el.removeEventListener("click", submitData.bind(this))
})
}

above implementation will work well, but there is a issue in removing event listener.

// remove event registered
el.removeEventListener("click", submitData.bind(this))

Here event won’t be removed because of

when you set the context using bind, a new function is created.

Methods are object in javascript and two object even with same value are not equal when doing comparision with “==” operator.

The above screenshot verify that method created using bind even with same value are not equal.

Now, coming back to our solution. With this implementation we have created a memory leak in our code as element button has a event. So button won’t be removed by garbage collector.

That’s why i said use “bind with caution”.

This is a common mistake & mostly when using es6 class. Where we use class method as event listener and in order to preserve the value of “this”, we use bind.

e.g -

class User {    constructor(name) {
this.name = name;
}
registerEvent() {
var el = document.querySelector('#btnSubmit');
el.addEventListener('click', this.onSubmit.bind(this));
}
onSubmit() {
console.log("name", this.name);
}
clearEvent() {
var el = document.querySelector('#btnSubmit');
el.removeEventListener('click', this.onSubmit.bind(this));
}
}
const user = new User("ujjwal gupta");
user.registerEvent();
user.onSubmit();
user.clearEvent();

Let’s correct this -

function submitData() {
fetch("url", {
data: {
name: this.firstName + ' ' + this.lastName,
gender: this.gender,
address: this.address,
isNewuser: true
}
})
}
var el = document.querySelector('#btnSubmit');
var submitDataWithContext = submitData.bind(user);
el.addEventListener('click', submitDataWithContext);

Here we have stored the method in a variable “submitDataWithContext” and using the variable in registering event.

Now if we will remove the event by supplying “submitDataWithContext”, then event will be removed as this is same value which was used to register event.

el.removeEventListener('click', submitDataWithContext);

I will leave the implementation of showing “message after data submission” to you guys.

Thanks for reading it. If you found this article useful, please share this with your friend & don’t forget to clap :).

--

--

Ujjwal Gupta

Frontend lead Polygon | Creator of jsstore, mahaljs | sqlweb, fortjs | opensource creator | we3, blockchain, solidity | javascript