The this
keyword has been associated with a lot of confusion. The use of the this
keyword depends on context i.e. where it is used. It is associated with object, method, or function through binding.
Binding allows us to set which object will be bound by
this
keyword
There are two types of binding:
Implicit: which is implied but not stated directly(manually).
Explicit: which is stated manually.
Now let's get started with the Implicit Binding of the
this
keyword for various use cases:
- In a method of object
Here this
keyword represents the object in which method is declared. Let's understand this with an example:
const student = {
name: "Nikhil",
birthYear: 1999,
gender: "Male",
education: "Graduate",
calcAge(){
return 2021 - this.birthYear
}
}
console.log(student.calcAge()); //22
In above example, this
represents student
object. We know this because, to the left of the dot(.) operator adjacent to the function calcAge()
, we see the student
object.
- In the function expression/ declaration
Here this
keyword represents the Global Object of window. Let's understand this with an example below.
- In the function expression/declaration (in strict mode)
Here this
keyword represents undefined
in strict mode. Let's understand this with code snippet below.
- In Event Handlers/Listeners
Here this
keyword points to the element on which the event is handled/listened. Let's understand by code snippet.
- When used in Global context, alone and independent
this
keyword points towindow
object
- In arrow functions
Here this
keyword represents the owner
of the arrow function. Let's take an example to understand this.
Hence we should avoid using arrow functions in event listeners.
- When an object is created using the new keyword
The new
keyword is used to create an object from the constructor
function.
let Player = function(name, position){
this.name = name,
this.position = position
this.aboutPlayer= function(){
console.log(`${this.name} plays at ${this.position}`);
}
}
let Cristiano = new Player('Cristiano Ronaldo', 'Forward')
let Beckham = new Player('David Beckham', 'Midfield')
Here the function player is invoked by a new
keyword. In this case, the new
keyword represents the object for which it is created. So in the first case this
represents Cristiano
and in the second it represents Beckham
.
Let's move to Explicit Binding of
this
keyword. There are three special methods, call(), apply(), bind() that help in achieving explicit binding.
Let's take a look at each one of them along with example.
- call() method
The call()
method allows for a function/method belonging to one object to be assigned and called for a different object.
Let's see how it works with an example:
const levelOfEducation = function(){
console.log(this.education);
}
const student = {
name: "Nikhil",
birthYear: 1999,
gender: "Male",
education: "Graduate",
calcAge(){
return 2021 - this.birthYear
}
}
levelOfEducation.call(student) // Graduate
Here call()
method is invoked by levelOfEducation()
, which further logs this.education
. But now the function looks for this
keyword, so that gets determined by parameter passed in call()
method. In this way, this
is explicitly binded with a particular object.
Now suppose the function which we want to call requires parameters, we can also pass in the parameters in call()
method.
const aboutEducation = function(university,place){
console.log(`${this.name} is ${this.education} from ${university}, ${place}.`);
}
aboutEducation.call(student,'XYZ','Mumbai') // Nikhil is Graduate from XYZ, Mumbai.
Now here's the pain point: Let's say we have more parameters we will have to pass each one of them. Passing individually each parameter is a hectic way and to optimize it we have the apply()
method.
- apply() method
The apply()
method solves the pain of passing parameters individually by allowing to pass an array of arguments. Let's understand this by example.
const educationInfo = ['XYZ','Mumbai',2021]
const aboutEducation = function(){
console.log(`${this.name} is ${this.education} from ${educationInfo[0]}, ${educationInfo[1]} in year ${educationInfo[2]}`);
}
aboutEducation.apply(student,educationInfo)// Nikhil is Graduate from XYZ, Mumbai in year 2021
So here we understand that when we have only one
value argument or no arguments to pass we use call()
, when we have multiple
value arguments to pass we use apply()
.
- bind() method
The bind()
method is similar to call()
method but with one difference. The call()
method invokes the function directly, but bind()
method returns a new function
and we can invoke that instead.
Let's understand this with an example:
const aboutEducation = function(university,place){
console.log(`${this.name} is ${this.education} from ${university}, ${place}.`);
}
const newFunction = aboutEducation.bind(student,'XYZ','Mumbai')
newFunction() // Nikhil is Graduate from XYZ, Mumbai.
The
bind()
method also allows an object to borrow a method from another object without making a copy of that method. This is overall a vast topic for some other day.
Conclusion:
Implicit Binding
In the method of an object
this
references to the object itself.In function expression/declaration it references Window object. On the other hand in
strict
mode it is undefined.In the arrow function,
this
references the owner of the function.In Event Handlers,
this
references the element on which event is handled.In objects created with
new
keyword using constructor functions,this
references the object itself.In alone and independent,
this
references Window object.
Three methods to bind this
keyword explicitly
call(): It is used when one value or no arguments are to be passed to the function.
call(object, argument-1,...,argument-n)
apply(): It is used when multiple value arguments are passed to the function. It allows us to pass array as a argument.
apply(object, array)
bind(): It is similar to
call()
, only difference is it returns a brand new function, which can be invoked later.
Woohoo! 🥳 I hope after reading this long article with patience you must have got complete clarity about this
keyword in JS.
If you find it useful do share it with your friends.
Make sure you follow me on Twitter. I will be posting more such articles. Thanks for reading it till the end.
Top comments (4)
it's great article
Thanks Zakimax!
Thanks
Thank you Nate!
It actually inspires to publish more.