Call Apply and Bind

Table of contents

In this article, we will explore the fundamental concepts behind Call, Apply, and Bind methods and examine how they can be utilized to enhance your JavaScript code. By the end of this article, you will have gained a clear understanding of the distinctions between Call, Apply, and Bind, as well as their applications in various programming scenarios.

Before going to these concepts first, let's understand why we need to use them or how they can make our code cleaner and shorter.

// making an object
const name = {
  firstName: "Jitender",
  secondName: "Singh",
  printFullName: function () {
    console.log(this.firstName + " " + this.secondName);
  },
};

console.log(name.firstName)  // Jitender
console.log(name.printFullName) // Jitender Singh

Now the problem arises here is that we have made one more object:

const name2:{
firstName:"Karan",
secondName:"Singh",
}
console.log(name2.printFullName); // undefined

We can't access that function inside our name2 object. But we know that Functions allow us to encapsulate a block of code and reuse it multiple times.

so here we can't reuse that function again and again.

Here these methods come into the picture.

Call()

It allows you to borrow a function from one object and execute it in the context of another object. Also it invoke the function immidiately.

Let's understand it with the help of an example

const name = {
  firstName: "Jitender",
  secondName: "Singh",
  printFullName: function () {
    console.log(this.firstName + " " + this.secondName);
  },
};

const name2 = {
  firstName: "Karan",
  secondName: "Singh",
};

// function borrowing
name.printFullName.call(name2);

Let's breakdown the above code

  1. We have a function printFullName that we want to call.

  2. Normally, when we call printFullName, this inside the function refers to the object that the function is a property of (the owning object). Here the this refers to name

  3. When we use call, we can explicitly set the value of this for printFullName to a specific object of our choice.

  4. We pass the object we want to set as this is the first argument to call, also we can pass additional arguments to the printFullName function.

Call method with arguments.

const name = {
  firstName: "Jitender",
  secondName: "Singh",
  printFullName: function (state, homeTown) {
    console.log(this.firstName + " " + this.secondName + " " + "state" + " "+                             
        state +" " +"hometown" +" " + homeTown
    );
  },
};
name.printFullName.call(name2, "Delhi", "Uttrakhand");
// Karan Singh state Delhi homeTown Uttrakhand

Apply ()

It is similar to the Call method the only difference here is that in the apply method instead of passing individual arguments to a function, it takes an array-like object as its second argument and applies the function with those arguments.Similar to the above it also invoke the function immidiately.

Example

const person = {
  name: 'John',
  greet: function(message, punctuation) {
    console.log(message + ', ' + this.name + punctuation);
  }
};

const anotherPerson = {
  name: 'Jane'
};

person.greet('Hello', '!');  // Output: Hello, John!
person.greet.apply(anotherPerson, ['Hi', '!!!']);  // Output: Hi, Jane!!!

Using apply, we can borrow the greet function and execute it in the context of the anotherPerson object. By calling person.greet.apply(anotherPerson, ['Hi', '!!!']), we set this to anotherPerson and pass an array ['Hi', '!!!'] as the arguments. As a result, it outputs "Hi, Jane!!!" because this.name now refers to another person.name and the array elements are passed as individual arguments.

Advantages of using apply() over call()

  1. apply takes an array-like object as its second argument, you can pass an array of arguments of any length. This is useful when you have a function that expects a variable number of arguments or when the arguments are generated dynamically at runtime.

  2. using apply may offer performance benefits compared to call. When dealing with a large number of arguments, passing them individually using call can be less efficient than passing them as an array-like object using apply.

Bind()

The bind Method is different from the above two methods. It creates a new function that is bound to a specific object as its this value. Unlike call and apply, bind doesn't immediately invoke the function but rather returns a new function that can be called later.

Example

const person = {
  name: 'John',
  greet: function() {
    console.log('Hello, ' + this.name);
  }
};

const anotherPerson = {
  name: 'Jane'
};

const greetPerson = person.greet.bind(anotherPerson);
console.log(greetPerson) // returns a function [Function: bound greet]

// To see the output we have to call that function 
greetPerson();  // Output: Hello, Jane

In this example, we have an object person with a greet method. We want to bind the greet function to the anotherPerson object. By calling person.greet.bind(anotherPerson), we create a new function called greetPerson that is bound to anotherPerson. When we invoke greetPerson(), it outputs "Hello, Jane" to the console because the this value inside greetPerson is set to anotherPerson.

The bind method is particularly useful when you want to create a function with a preset this value that can be reused multiple times. It allows you to create a "bound" function that maintains a specific context regardless of how or when it's called.

In conclusion, the call, apply, and bind methods in JavaScript are powerful tools that enhance the flexibility and reusability of functions. They enable us to manipulate the execution context, pass arguments, and create bound functions with predefined contexts. By understanding and effectively utilizing these methods, JavaScript developers can unlock new possibilities and write more modular, efficient code.

Happy Coding

Did you find this article valuable?

Support jitender singh by becoming a sponsor. Any amount is appreciated!