Open In App

Explain call(), apply(), and bind() methods in JavaScript

Last Updated : 12 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Before implementing bind(), apply(), and call() polyfills, let us know what is a polyfill in JavaScript:

Polyfill: Polyfills are the implementation of the features that are given by our browsers, but may not be present in the previous versions of it.

1. Bind() Method: The bind() method creates a new function and when that new function is called it set this keyword to the first argument which is passed to the bind method, and if any other sequences of arguments preceding the first argument are passed to the bind method then they are passed as an argument to the new function when the new function is called.

 

Syntax:

bind(thisArg)
bind(thisArg, arg1, arg2, /* …, */ argN)

Example 1: Let us first see what will be the actual output with the bind method that is given by javascript:

Javascript




let nameObj = {
    name: "Tony"
}
  
let PrintName = {
    name: "steve",
    sayHi: function () {
  
        // Here "this" points to nameObj
        console.log(this.name); 
    }
}
  
let HiFun = PrintName.sayHi.bind(nameObj);
HiFun();


Output:

Tony

Here we have an object “PrintName” which has a function sayHi which will print the name of the person which we pass in the nameObj object. Here we are binding nameObj with the PrintName sayHi function so that we can access nameObj in this in the PrintName sayHi function. The bind method returns a function so that when we call this function sayHi will have this as nameObj.

Example 2: Now let us write our own bind polyfill.  We will implement our bind polyfill using a prototype on the Object class in the above example:

Javascript




let nameObj = {
    name: "Tony"
}
  
let PrintName = {
    name: "steve",
    sayHi: function () {
        console.log(this.name);
    }
}
  
Object.prototype.MyBind = function (bindObj) {
  
    // Here "this" will be sayHi function
    bindObj.myMethod = this;
    return function () {
        bindObj.myMethod();
    }
}
let HiFun = PrintName.sayHi.MyBind(nameObj);
HiFun();


Output:

Tony

Explanation: So our bind polyfill is giving the same output as the previous bind method. So now let us see actually what we are doing.  In the Object prototype, we are attaching our MyBind function. Our MyBind function takes an object(In our case nameObj) as a parameter that we want to bind with our PrintName sayHi function.  

Now, let us only focus only on this part of the code (Object.prototype.MyBind):

Object.prototype.MyBind = function (bindObj) {

   // Here "this" will be sayHi function
   bindObj.myMethod = this;
   return function () {
       bindObj.myMethod();
   }
}

Here we have the MyBind function with a parameter as bindObj in our case our bindObj is nameObj. So actually what we are doing?  we are adding myMethod inside nameObj and inside myMethod we are storing this. In our case, this is the sayHi function. 

Example 3: So let us first look at how our bindObj is looking after running the “bindObj.myMethod=this” line.

Javascript




let nameObj={
    name:"Tony"
}
  
let PrintName={
    name:"steve",
    sayHi:function(){
        console.log(this.name);
    }
}
  
Object.prototype.MyBind=function(bindObj) {
  
    // Here "this" will be sayHi function
    bindObj.myMethod=this
    console.log("bindObj ->",bindObj);
    return function(){
        bindObj.myMethod();
    }
}
let HiFun=PrintName.sayHi.MyBind(nameObj);


Output:

bindObj -> { name: 'Tony', myMethod: [Function: sayHi] }

Here, I have not called HiFun() because we wanted to see only how the bindObj looks after running “bindObj.myMethod=this”. We can clearly see that in bindObj we have myMethod which has the sayHi function. We can also see a pictorial representation of bindObj after running the “bindObj.myMethod=this” line. If we cannot understand the output above from the code below:

let bindObj = {
   name: "Tony",
   myMethod: function sayHi() {

       // Here 'this' will be bindObj
       console.log(this.name);
   }
}

So, why we are doing all this? We wanted to access nameObj in this inside the sayHi function of PrintName.We wanted to write polyfill of a bind. So instead of attaching nameObj to this in the sayHi function. What we are doing is that in nameObj itself we are creating a myMethod and in myMethod we are adding the sayHi function of PrintName and then we are returning a function in MyBind in which we are calling bindObj.MyMethod() which basically means nameObj.myMethod() because of this when the sayHi function inside nameObj will be called it will contain itself in this and the name which is present in nameObj i.e Tony will be printed.

Example 4: Let us see one more example of bind polyfill when parameters are passed to our MyBind method :

Javascript




let nameObj = {
    name: "Tony"
}
  
let PrintName = {
    name: "steve",
    sayHi: function (age) {
        console.log(this.name + " age is " + age);
    }
}
  
Object.prototype.MyBind = function (bindObj, ...args) {
    bindObj.myMethod = this;
    return function () {
        bindObj.myMethod(...args);
    }
}
let HiFun = PrintName.sayHi.MyBind(nameObj, 42);
HiFun();


Output: 

Tony age is 42

Here “…args” is the rest parameter that puts n number of inputs into a javascript array. Here “…args” will be [42]

Call() Method: The call() method calls the function directly and sets this to the first argument passed to the call method and if any other sequences of arguments preceding the first argument are passed to the call method then they are passed as an argument to the function.

Syntax:

call(objectInstance)
call(objectInstance, arg1, /* …, */ argN)

Example 1: Before implementing our own call polyfill let us see the call method which is given by javascript

Javascript




let nameObj = {
    name: "Tony"
}
  
let PrintName = {
    name: "steve",
    sayHi: function (age) {
        console.log(this.name + " age is " + age);
    }
}
  
PrintName.sayHi.call(nameObj, 42);


Output: 

Tony age is 42

NOTE: The call method doesn’t return a new function.

Example 2: Now let us write our own call polyfill:

Javascript




let nameObj = {
    name: "Tony"
}
  
let PrintName = {
    name: "steve",
    sayHi: function (age) {
        console.log(this.name + " age is " + age);
    }
}
  
Object.prototype.MyCall = function (bindObj, ...args) {
    bindObj.myMethod = this;
  
    bindObj.myMethod(...args);
  
}
PrintName.sayHi.MyCall(nameObj, 42);


Output: 

Tony age is 42

This is exactly the same as the MyBind function but this only doesn’t return a function because the call method given by javascript also doesn’t return a method. So while implementing the polyfill of call we also need to keep this in mind.

Apply() Method: The apply() method calls the function directly and sets this to the first argument passed to the apply method and if any other arguments provided as an array are passed to the call method then they are passed as an argument to the function.

Syntax:

apply(objectInstance)
apply(objectInstance, argsArray)

Example 1: For the final time let us see apply method given by javascript:

Javascript




let nameObj = {
    name: "Tony"
}
  
let PrintName = {
    name: "steve",
    sayHi: function (...age) {
        console.log(this.name + " age is " + age);
    }
}
PrintName.sayHi.apply(nameObj, [42]);


Output: 

Tony age is 42

In the apply method, we pass arguments in the form of an array this is only the primary difference between call and apply.

Example 2: Now let us write our final polyfill which is apply polyfill:

Javascript




let nameObj = {
    name: "Tony"
}
  
let PrintName = {
    name: "steve",
    sayHi: function (age) {
        console.log(this.name + " age is " + age);
    }
}
  
Object.prototype.MyApply = function (bindObj, args) {
    bindObj.myMethod = this;
  
    bindObj.myMethod(...args);
  
}
PrintName.sayHi.MyApply(nameObj, [42]);


Output: 

Tony age is 42

Now in this apply polyfill, we only need to pass an array as a parameter. Rest is the same as call polyfill.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads