Easiest way to understand CAB(Call, Apply, Bind) in JS

The keyword this in JavaScript is one of the most muddling concepts because its value depends on where it is used. Often it tricks developers and sometimes it's the culprit behind surreal results.

Let's discuss this this keyword with simple and easy-to-understand examples before actually delving into the call, apply, and bind methods as this keyword is the main reason for having those methods.

What is this in JavaScript?

The this keyword in JavaScript refers to the object that the function is a property of and this will depend on the object that is invoking the function.

To get a quick idea of this have a look at the code snippet below.

const myObj = {
  name: 'John',
  age: 25,
  place: 'London',
  myFunction: function() {
    return this;
  }
};

myObj.myFunction(); 
// {name: "John", age: 25, place: "London", myFunction: ƒ()}

In the above code snippet, you can see that when myFunction method is called it returns the value of this, which is nothing but the myObj itself. If you recollect the definition for this in the previous paragraph, it says this refers to the object that the function is a property of, so here myFunction is a property of myObj, which means this is referring to that myObj object.

A simple trick is whatever precedes before .(dot) is the object referenced by the this keyword. So before .(dot) in myObj.myFunction() is myObj, which is the value of this.

Let's take another example to understand this.

function myFunction() {
  return this;
}

myFunction(); // window or undefined(in case of 'strict mode')

In the above code we are returning this from the myFunction, so when myFunction is called what we see or get is the value of this.

Again if we recollect our definition of this, it refers to the object which the function is a property of. Here our function myFunction is a property of global object nothing but the window object in the browser, so which means when we call myFunction the value of this is going to be the window object. 

If we go by our trick of .(dot) preceding the function, here there's no dot but every function is a method in the window object, so it translates to window.myFunction() so here, the this keyword refers to the window object. 

In order to avoid functions getting attached to the window object, we use strict mode so as a result window will be undefined in such cases. 

So keep in mind our definition as we're going to use that for understanding call, apply and bind methods. 

The this keyword in JavaScript refers to the object that the function is a property of and this will depend on the object that is invoking the function.

Understanding call, apply, bind in JavaScript

Let's consider an object person with a property name and a method details.

const person = {
  name: 'John',
  details: function(age, place) {
    return `${this.name} ${age} years old, lives in ${place}`
  }
}

person.details(25, 'London'); //John 25 years old, lives in London

When we call the method details on person object with the arguments, we knew that this refers to the person object because details is a property of the person object and so this.name would be John and so the result that gets returned will be as shown in the comments.

This part is going to be clear as we knew what this means in the person object.

Let's consider a scenario where we wanted to use the details method but with different arguments.

As per the details method we can pass in different age and place values but how about the name, as it is connected with the this keyword? This is where we are going to use those special methods call, apply and bind. Let's dive into those.

Using call method

Now we want to associate a different object other than person to this keyword of details method. So to do that we're going to use the call method as shown below in the code snippet.

person.details.call({ name: 'James'}, 30, 'Tokyo'); 
// James 30 years old, lives in Tokyo

A call method takes a new object that we want this to refer to followed by the arguments to the function(nothing but the details method) and it gets called referencing this to the new object passed as the first argument. Voila! That's what a call method is. 

Using apply method

Guess what, apply method is just the same as the call method, that is, it takes a new object as the first argument to reference the this keyword and is followed by an array of arguments. So it means you can simply pass the arguments to the details function in the form of an array instead of passing individually. Have a look at the code below so it becomes clear for you.

person.details.apply({ name: 'James'}, [30, 'Tokyo']); 
// James 30 years old, lives in Tokyo

So call and apply methods are used to reference a new object to this keyword on methods.

And then what bind is for? Guess!

Using bind method

When call and apply methods are applied they are called(invoked) directly referencing the new object passed but in order to get a new function reference that can be used to call at later times, the bind method is used. Have a look at the code snippet below to get more clarity.

const personDetails = person.details.bind({name: 'William'}, 40, 'Rome');

personDetails(); 
// William 40 years old, lives in Rome

So using the bind method returns a new function reference which can be called at a later time and that is all about the bind method.

So putting all the three methods together.

const person = {
  name: 'John',
  details: function(age, place) {
    return `${this.name} ${age} years old, lives in ${place}`
  }
}

person.details(25, 'London');  //John 25 years old, lives in London

// Using call
person.details.call({ name: 'James'}, 30, 'Tokyo'); // James 30 years old, lives in Tokyo

// Using apply
person.details.apply({ name: 'James'}, [30, 'Tokyo']); // James 30 years old, lives in Tokyo

// Using bind
const personDetails = person.details.bind({name: 'William'}, 40, 'Rome');
personDetails();  // William 40 years old, lives in Rome

So in short CAB(call, apply, bind in JavaScript) are used to reference a new owner object to the this keyword. Hope this article has demystified the call, apply and bind methods in JS.

Did we miss anything here? Yes, the this value will be different when we use an arrow function. See you in the next article.

If you liked this article please give a follow & share. More such interesting articles with tips are on the way.

32