call(), bind() and apply() in Javascript
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
Subscribe to my newsletter
Read articles from Twinkal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by