Difference between call, apply and bind functions in JavaScript.

call, apply and bind methods are used to explicitly bind this object to a function. this keyword refers to an object which is executing the current code. These three methods are very useful to bind this to methods when you don't know how your function will be called or you don't have control on the excution context in which your method will be call.

Let's take a look at an example-

const hero = { name: "Batman", age:27, printInfo: function(){ alert(`name: ${this.name}, age: ${this.age}`) } } hero.printInfo(); // name:Batman, age: 27

In above example, we have a hero object, and printInfo method of hero object is using this keyword to print hero's information. executing hero.printInfo() prints the correct user info by using this keyword because printInfo is executing in hero object's context.

Now let say we want to print user info on user actions, for example on a button click. Let's assume that we have a HTML button.

// get the button const button = document.getElementById("print-info-btn"); // add click event listener, and pass hero.printInfo button.addEventListener("click", hero.printInfo);

On button click, hero.printInfo function will be called and will not be able to print correct user information. Because on button click, the object which is executing hero.printInfo method is button object, and the this keyword inside hero.printInfo method is also refering to the HTML Button elemnt.

In these kind of situation where you don't know in advance which object will execute your function once you passed it as callback to some other function, call, apply and bind method are useful to bind this keyword to whatever object you want to bind.

Every function in JavaScript have these three methods which allow us to specify the context in which the function will be invoked. Let's see them one by one.

bind Method

bind method binds this keyword and returns a copy of a function which will have this keyword set to provided value.

Let' see how can we solve our button click issue. Instead of passing hero.printInfo to addEventListener , we will explicitly bind this to be equal to hero object.

// get the button const button = document.getElementById("print-info-btn"); const boundedMethod = hero.printInfo.bind(hero) button.addEventListener("click", boundedMethod );

bind method creates a new function, then it binds the this keyword of newly method to provided object. bind method also accepts zero or more arguments, which will be passed to bounded/actual method.

Let's modify printInfo method to accept some arguments -

const hero = { name: "Batman", age:27, printInfo: function(favouriteColor){ alert(`name: ${this.name}, age: ${this.age}, favourite color: ${favouriteColor}`) } }

bind method's first argument is the context and after that you can pass multiple arguments one by one. In our case first parameter is the context and second paramter is favouriteColor.

const boundedMethod = hero.printInfo.bind(hero, "black") button.addEventListener("click", boundedMethod );

bind method doesn't modify existing function, instead it creates and return a new function and bind the this keyword to provided value.

call Method

call method is exactly same as bind except instead of creating a new function, call method instantly executes the funtion with provide object as this keyword.

const batman = { name:"Bruce Wayne", }; function sayHi(){ console.log(`Hi, I'm ${this.name} `) } sayHi(); // Hi, I'm undefined

In above example, We have sayHi method which prints the name property of this object. If we call sayHi method without any context as we did in above example, the this keyword in sayHi will refer to global object. So how do we invoke sayHi method such that the this keyword inside sayHi method refers to batman object, we can't do batman.sayHi() because batman object doesn't have sayHi method.

We can use call method to invoke sayHi method in context of batman object.

sayHi.call(batman) // Hi, I'm Bruce Wayne

call method's first argument is the context object and after the first argument you can pass multiple argument one by one. Let's modify sayHi method to accept 3 additional arguments.

function sayHi(lang1, lang2, lang3){ console.log(`Hi, I'm ${this.name}, i can speak ${lang1}, ${lang2}and ${lang3} `) }

We can pass lang1, lang2 and lang3 parameter to sayHi method like this -

sayHi.call(batman, "English", "Spanish", "French"); //Hi, I'm Bruce Wayne, i can speak English, Spanish and French

call method doesn't modify existing function, nor does it creates a copy of function.

apply Method

apply method is exactly same as call, but instead of passing multiple arguments one by one, apply method accepts an array as its second argument and it will spread out array elements as arguments to the function.

instead of

sayHi.call(batman, "English", "Spanish", "French");

apply accpets an array

const languages = [ "English", "Spanish", "French"]; sayHi.apply(batman, languages);

Conclusion

call, apply and bind method are available on every function in JavaScript and they are used to explicitly bind this keyword to given function. bind method binds the this and always creates and return a new copy of given function. Wheres call and apply methods instantly invoke the funtion with provide object as this keyword.

Say Hi on twitter and email

Designed and developed by Gulam Hussain.

Built with Gatsby. Hosted on Netlify.