Mastering JavaScript: Understanding call, bind, and apply
Tags: javascript, frontend, webdev, programming
Published: 2024-05-16 07:57:26

JavaScript is a versatile language with numerous built-in methods and functions that empower developers to create robust and efficient applications.

Among these, the call, apply, and bind methods stand out as powerful tools for manipulating the context of functions and managing how they're executed.

Also Explain call, apply & bind is one of the most popular interview questions 😎

In this comprehensive guide, we'll delve into the intricacies of call, apply, and bind, demystifying their functionality and showcasing their practical applications.

Let's get started 🥳

## Why are these methods needed?

Let's take an example.

```javascript
class Person {
    constructor(name, email, contact){
        this.name = name;
        this.email = email;
        this.contact = contact;
    }
}

class Vehicle {
    constructor(name, type, number){
        this.name = name;
        this.type = type;
        this.number = number;
    }
}
```

Consider these two classes. Let's say we want to print name of the person & vehicle.

What options do we have here?

We can add printName method to each of the classes. This way each class can have its own method. But the method would do exact same thing i.e. print the name.

So does it make sense to write duplicate code? What if we could write one generic print method & it could be shared between these classes?

This is exactly where `call` `apply` & `bind` come into picture.

## How do these methods help?

Let's understand how we can solve this code duplication problem using these methods.

## Call

Using `call` method, we can pass the context of Person & Vehicle classes & call the function printName .

Since printName has access to context of Person & Vehicle, it can access properties & methods of respective classes.

Call method allows to share generic functions between Classes & Objects.

```javascript
const printName = function() {
    console.log('Name: ', this.name);
}

const person = new Person('abc', 'abc@gmail.com', '8768876543');

const vehicle = new Vehicle('aventador', 'sports', 'MJ10DS8765');

printName.call(person);
printName.call(vehicle);

// Output
// Name: abc
// Name: aventador

// What if we want to pass arguments to printName method?
// We can do like this
const printNameAndNumber = function(number) {
    console.log(this.name + ' has number ' + number);
}

printNameAndNumber.call(person, "8768876543");
printNameAndNumber.call(vehicle, "MJ10DS8765");

// Output
// abc has number 8768876543
// aventador has number MJ10DS8765
```

> 💡 You can pass any number of arguments to call method in CSV format. Remember, first argument always has to be the context & from second argument onwards you can pass anything.

## Apply

`apply` method does the exact same things as the call method.

The only difference is the way you pass the arguments.

```javascript
const printNameAndNumber = function(number) {
    console.log(this.name + ' has number ' + number);
}

const person = new Person('abc', 'abc@gmail.com', '8768876543');

const vehicle = new Vehicle('aventador', 'sports', 'MJ10DS8765');

printNameAndNumber.apply(person, ["8768876543"]);
printNameAndNumber.apply(vehicle, ["MJ10DS8765"]);

// Output is exactly as that of call method
// abc has number 8768876543
// aventador has number MJ10DS8765
```

> 💡In apply method, instead of passing arguments in CSV format, you pass an array of arguments. Remember, the first argument always has to be the context just like call method.

## Bind

`bind` method does the exact same things as the call method.

The only difference is instead of calling the function immediately, it creates a reference to that function & returns the reference.

We can save the reference for future use.

```javascript
const printNameAndNumber = function(number) {
    console.log(this.name + ' has number ' + number);
}

const person = new Person('abc', 'abc@gmail.com', '8768876543');

const vehicle = new Vehicle('aventador', 'sports', 'MJ10DS8765');

const printPersonDetails = printNameAndNumber.bind(person, "8768876543");
const printVehicleDetails = printNameAndNumber.bind(vehicle, "MJ10DS8765");

printPersonDetails();
printVehicleDetails();

// Output is exactly as that of call method
// abc has number 8768876543
// aventador has number MJ10DS8765
```

I hope this blog was really helpful 😄😉

Go ahead & start leveraging these methods in your code 😎

And yes, if anyone asks these methods in the interviews, nail them ❤️