call(), bind() and apply() in Javascript

TwinkalTwinkal
3 min read

In Javascript, everything is an Object. In other object-oriented programming languages, the this keyword always refers to the current instance of the class. Whereas in JavaScript, the value this depends on how a function is called.

const person = {
firstName: "AAA",
lastName: "BBB",
printFullName: function() {
    console.log(this.firstName + " " + this.lastName)  // AAA BBB
    }
}
person.printFullName()

/* but what if we try to write the same using reference */

const person = {
firstName: "AAA",
lastName: "BBB",
printFullName: function() {
    console.log(this.firstName + " " + this.lastName)  // undefined undefined
}
}

const FN = person.printFullName 
FN();

Here, we are storing a reference of person.printName to FN variable. After that, we are calling it without an object reference, so this will now refer to the window (global) object.

So, here this keyword inside a function refers to objects depending on how a function is called. In the first trial, the function is called on an person object so this refers o a person object and its properties. whereas in the second trial, the printFullName functions reference is stored in FN. now, FN refers to global objects.

This way, sometimes we accidentally lose reference to the this variable. So how can we prevent that from happening?

We use call, bind and apply methods to set the this keyword independent of how the function is called.

Javascript functions are a special kind of object. So they have access to some methods and properties. So every function in JavaScript inherits those methods. Call, bind, and apply are some of the methods that every function inherits.

function greet() {
    console.log("Hi")
}

greet.time = "morning" /* example to shows that Javascript functions 
are a special kind of object  */

greet()  //  Hi
console.log(greet.time)  // morning

Bind()

The bind method creates a new function and sets this keyword to the specified object.




const person2 = {
  name: 'BBB',
  age: 22,
};

function greeting() {
  console.log(`Hi, I am ${this.name} and I am ${this.age} years old`);
}

const greetingPerson1 = greeting.bind(person1);
greetingPerson1();  // Hi, I am AAA and I am 24 years old

const greetingPerson2 = greeting.bind(person2);
greetingPerson2();  // Hi, I am BBB and I am 22 years old

Here greeting.bind(person1) creates a new function with this set to person1 object, which we then assign to greetingPerson1 variable. Similarly for greetingPerson2.

Bind() can also accept arguments

function greeting(ln) {
  console.log(`Hi, I am ${this.name} and I am ${this.age} years old , I speak ${ln}`);
}

const greetingPerson1 = greeting.bind(person1, "english");
greetingPerson1();  // Hi, I am AAA and I am 24 years old , I speak english

We can also pass extra arguments to the bind method. The general syntax for this is function.bind(this, arg1, arg2, ...).

Call()

The call method sets the this inside the function and immediately executes that function.

The difference between call() and bind() is that the call() sets the this keyword and executes the function immediately and it does not create a new copy of the function, while the bind() creates a copy of that function and sets the this keyword.

call() can also accept the arguments.

const person1 = {
  name: 'AAA',
  age: 24,
};
function greeting() {
  console.log(`Hi, I am ${this.name} and I am ${this.age} years old`);
}
greeting.call(person1,"english")  // Hi, I am AAA and I am 24 years old , I speak english

Apply()

The apply() method is similar to call(). The difference is that the apply() method accepts an array of arguments instead of comma-separated values.

const person1 = {
  name: 'AAA',
  age: 24,
};
function greeting1(greet,ln) {
  console.log(`${greet}, I am ${this.name} and I am ${this.age} years old , I speak ${ln}`);
}
greeting1.apply(person1, ["Hi", "spanish"])  // Hi, I am AAA and I am 24 years old , I speak spanish
10
Subscribe to my newsletter

Read articles from Twinkal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Twinkal
Twinkal