The Behaviour of the 'this' Keyword In Traditional Functions vs. Arrow Functions
The 'this'
keyword is one of the most confusing aspects of the JavaScript language. Many developers find themselves puzzled by its behaviour and struggle to understand what it represents. If you've faced this issue as well, rest assured, you're not alone.
After reading this blog, I can guarantee that your understanding of the 'this'
keyword will be much more clear.
The behaviour of 'this'
In Traditional Functions
JavaScript's 'this'
keyword used in a function refers to the object it belongs to. I know you have heard this sentence a thousand times. Just kidding, it might be a few times :) Let's see what it really means.
Before understanding the 'this
' keyword, let's look at the simple function calls.
fucntion sayMyName(name){
console.log(`My name is ${name}`);
}
sayMyName("Abhijeet")
Looking at the function, if I were to ask you what the value of the name
parameter is, you would say it entirely depends on what is passed to the function when calling it. In this case, I have passed my name
as "Abhijeet", so its value is "Abhijeet". If I were to pass "Rahul", its value would be "Rahul".
Similarly, in traditional JavaScript functions, the value of the 'this'
keyword is entirely dependent on how the function is called.
There are four ways to determine the value of the 'this'
keyword:
Implicit binding
Explicit binding
New binding
Default binding
Don't worry, we will look at each of these, one by one.
- Implicit binding
When we call a function by object.function()
syntax, this is called implicit binding and the 'this'
keyword represents the object to the left of the function.
const person = {
name: 'Simran',
sayMyName: function () {
console.log(this)
console.log(`My name is ${this.name}`)
}
}
person .sayMyName()
- Explicit Binding
Every function in JavaScript has a property 'call'
. We can use this property to call the function with an object passed as a parameter. And the object which is passed as a parameter represents the 'this'
keyword for that function call.
For example, in the below code example, there are two persons person1
and person2
with properties name
and city
. And we have one function which prints the 'this'
keyword and the name
. Let's say we want to print the name
of a person2
then how can we do it?
We can call the function with the 'call'
property and pass the object person2
as a parameter.
Explicit binding makes functions reusable for multiple objects.
function sayMyName (){
console.log(this)
console.log(`My name is ${this.name}`)
}
const person1 = {
name: "Abhijeet",
city: "Chandigarh,The City Beautiful",
}
const person2 = {
name: "Rahul",
city: "Mohali",
}
sayMyName.call(person2)
sayMyName.call(person1)
- New Binding
In JavaScript, we have constructor functions that we can call with a new keyword to create different objects of similar properties and methods. In the below example, we have a Person
constructor which has been used to create two persons person1
and person2
of the same property that is name
and age
but different values.
When we call the function with a new keyword the value of the 'this'
keyword is an empty object {}
and then properties defined in the function using the this.property = value
syntax are putten inside the { }
object and then it is returned automatically.
function Person(name,age){
console.log(this)
this.name = name;
this.age = age;
}
const person1 = new Person('Simran', 21)
const person2 = new Person('Rahul', 20)
- Default Binding
If none of the above conditions is met, default binding comes into the picture, and the 'this'
keyword refers to the global 'Window'
object in the case of browsers and [global this]
in the case of node
environment. Or simply we can say in normal function calls 'this'
keyword refers to the global 'window'
object.
function sayMyname(name){
console.log(name)
console.log(this)
}
sayMyname("Abhijeet")
Order of precedence for this Keyword
New binding
Explicit Binding
Implicit Binding
Default Binding
First, it is checked whether the function is called with a 'new'
keyword if yes then it represents an empty object { }
if not then it is checked for explicit binding, after that it is checked for Implicit binding. If these three conditions do not meet then 'this'
represents a global 'window'
object.
The Behaviour of 'this'
In Arrow Functions.
The behaviour of the 'this'
keyword in arrow functions is quite different from the traditional functions. In traditional functions, this keyword depends on how the functions are called while in arrow functions 'this'
keyword is evaluated based on where the arrow function is located.
Arrow functions themselves don't have the 'this'
keyword instead they use the value of their parent 'this'
. I know it is confusing. The key point to remember here is that in arrow functions 'this'
keyword is not dependent on how the function is called but instead on where the function is defined and who is its parent.
Let's see using example. Looking at the function call you might think it will print the fan
object but again I will repeat, it doesn't depend on how it is called instead where it is located. In this case, it is located inside a fan
object and the 'this'
keyword for a fan
object is 'window'
therefore its output will be the 'window'
object.
You must be thinking why 'this'
refers to the 'window'
for the fan
object, right? Because the fan object is defined inside the global context and in the global context 'this'
refers to the 'window'
object.
const fan = {
type: 'table',
price: 2000,
printFan: ()=>{
console.log(this)
}
}
fan.printFan()
Let's change the above example slightly. Now the arrow function printFan
is defined inside the traditional function, therefore, the fanDetails
function is the parent of the printFan
function. If you didn't understand read again slowly slowly.
Now we are calling the parent function fanDetails
using the implicit binding, therefore, the 'this'
keyword for the parent function will be the fan
object. And as we discussed above arrow functions don't have their own 'this'
keyword instead they use their parent 'this'
. Therefore, the 'this'
keyword for the printFan
function will also be the fan
object.
const fan = {
type: 'table',
price: 2000,
fanDetails: function(){
console.log('This keyword for parent fn: ', this)
const printFan = ()=>{
console.log('This keyword for child fn: ', this)
}
printFan();
}
}
fan.fanDetails()
Another difference between arrow functions and traditional functions is that we can't call arrow functions using the 'new'
keyword. Therefore, they cannot be used to create factory functions.
If you've reached this point, please leave a comment letting me know if this blog has helped you understand the concepts related to the 'this'
keyword better. Your feedback is important to me and will help me know if the blog has been effective in clearing up any confusion you might have had about the 'this'
keyword.
Thank you for your time and input!
Subscribe to my newsletter
Read articles from Abhijeet Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Abhijeet Singh
Abhijeet Singh
I am a Full Stack MERN Developer residing in Chandigarh, India. I have done Bachelor's degree in Computer Application from Punjab University, Chandigarh. With expertise in the MERN stack, I create innovative and captivating digital solutions. Continuously honing my skills and staying updated with the latest technologies, I strive to deliver impactful web applications that meet modern demands.