Mastering JavaScript's Call, Apply, and Bind Methods: A Comprehensive Guide

ยท

4 min read

Intro

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.

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.

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;
    }
}

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.

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.

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.

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 โค๏ธ

ย