Logic Behind "this" in JS
If you are learning JS(JavaScript) you have seen "this" keyword a lot. Generally, beginners try to remember the working of "this" in JS also sometimes they are told to remember it by their teachers. But after reading this blog thoroughly you will understand the logic behind "this". Now, if you are totally new to JS environment the working of "this" may surprise you but don't worry their is logic behind everything.
"this" and it's different values
The very basic and core thing to know about "this" keyword is that, it is always used for providing reference of something.
Value of "this" always depends upon on the environment in which we are executing our code.
In Global Context "this" always has the reference of global object.
The global object for browser is "Window object".
The global object for Node is node's object.
global --> {}Inside function:
if "use strict" is not mentioned explicitly: this have a reference of global object.
if "use strict" is mentioned explicitly: this have a value "undefined".
4 ways by which value of this is decided
Default Binding: In default binding value of "this" get binds to the global object of your environment it could be window object for browsers or could be global object of node. For example,
arrange()if their is "this" inside arrange function it will points to global object.Implicit Binding: In implicit binding value of "this" get binds to the object which is calling a method and inside this method we have used "this" keyword here this bind with that object.
obj.fun()here inside fun() we are using "this" and now value of "this" will be obj.Explicit Binding: In explicit binding we use methods like call, bind, apply to make "this" points to particular object . We will explore this further in the article.
Constructor Binding: In constructor binding whenever we call a constructor using new keyword it creates an instance of that function/class and now "this" points to this instance of that class.
Let's see example of these different binding so that you understand this properly.
const college = {
name: "XYZ Institute of Technology",
attendanceCriteria(){
return `${this.name} will not allow any student to sit in placement if his/her attendance is lower than 99.99%.`
}
}
console.log(college.attendanceCriteria());//Implicit Binding: this=>college
----------------------------------------------------------------
OUTPUT:
XYZ Institute of Technology will not allow any student to sit in placement if his/her attendance is lower than 99.99%.
function Student(name, college, attendanceCriteria){
this.name = name;
this.college = college;
this.attendanceCriteria = attendanceCriteria;
}
const abhishek = new Student("Abhishek", "XYZ IT", "95%"); // Contructor Binding
console.log(abhishek)
----------------------------------------------------------------
OUTPUT:
{
name: "Abhishek",
college: "XYZ IT",
attendanceCriteria: "95%"
}
Lets clear some myths about "this"
MYTH 1:
Majority of Developers who are working in JS environment usually thinks that there is no "this" in arrow function and they are correct, arrow functions do not have their own this, but it does not mean that they don't have any reference of "this". Let's understand this with one simple example.
const filmDirector = {
name: "Sanjay Leela Bhansali",
cast: ["Ranveer", "Deepika", "Priyanka"],
announceCast() {
this.cast.forEach((actor) => {
console.log(`\({this.name} introduces \){actor}`);
});
}
}
filmDirector.announceCast();
----------------------------------------------------------------
OUTPUT:
Sanjay Leela Bhansali introduces Ranveer
Sanjay Leela Bhansali introduces Deepika
Sanjay Leela Bhansali introduces Priyanka
here inside announce cast we are using this.name since inside forEach we are having an arrow function that means this should be undefined, but as you can see this is having a reference of filmDirector object.
Now let's understand this behavior of "this":
Please note how we are calling announceCast function
filmDirector.announceCast, can you see implicit binding happening here.For now this --> filmDirector object.
First time using this for accessing cast
this.casthere cast is of filmDirector object.Now lets come inside arrow function, inside arrow function we have used this to access name
this.name.We don't have "this" for arrow function that is correct but arrow function at the runtime check is their any value of this available in it's lexical environment if not it goes one level up and then check their if it found "this" their, now "this" inside arrow function points to that value of this .
Similar case is here, arrow function first check is their any "this" in it's lexical environment answer is no. so it goes one level up (now in the announceCast scope) here it finds this pointing to filmDirector object so at the runtime arrow function decide that this value inside it will point to filmDirector object.
MYTH 2:
Myth 1 gives birth to Myth 2 let's directly go on the code part
const filmSet = {
crew: "Spot boys",
prepareProps() {
console.log(`Outer this.crew: ${this.crew}`);
function arrangeChairs() {
console.log(`Inner this.crew: ${this.crew}`);
}
arrangeChairs();
const arrangeLights = () => {
console.log(`Arrow this.crew: ${this.crew}`);
};
arrangeLights();
},
};
filmSet.prepareProps();
----------------------------------------------------------------
OUTPUT:
Outer this.crew: Spot boys
Inner this.crew: undefined
Arrow this.crew: Spot boys
Yes, inner function gives undefined now do you want to know why:
As arrow function don't have their own this but they take value of this depending on the value of this in their lexical environment, but normal function have value of this but they never inherent value of this lexically this is the only reason behind this quirk.
Now here arrangeChairs is inside of prepareProps and we are calling arrangeChairs there only but not we are calling arrangeChairs by default binding means "this" inside arrangeChairs will point to global object because normal function never inherent value of "this" lexically.
The global object is node {} inside {} we don't have crew property so it is giving undefined as value here.
ABC: apply(), bind(), call() what are they ?
All three of these functions are used for passing new reference to "this".
There are three different ways by which we can explicitly give reference to "this" keyword . Let's understand each of them one by one
- call(): This function is used when you want to explicitly pass reference of some object to the function, with the reference of object you also have to pass the parameters of that function. One important point to note is that .call() executes immediately, means it does not return anything it just executes there only.
function cookDish(ingredient, style) {
return `\({this.name} prepares \){ingredient} in ${style} style!`;
}
const cityKitchen = { name: "City Delight Kitchen" };
console.log(cookDish.call(cityKitchen, "Paneer with aromatic spices", "Mughlai"));
----------------------------------------------------------------
OUTPUT:
City Delight Kitchen prepares Paneer with aromatic spices in Mughlai style!
Here, we are passing reference of cityKitchen object in cookDish function using .call() method, thing to note is that with reference to object we are passing the parameters which cookDish() function tells normally as a string.
- apply(): This function is same as call(), this function is also used for passing reference of object to the function but it differs in how we pass the parameters of the function. In call() we have to pass the parameter as the function demands but in apply() we have pass an array that array will be having all the parameter of that function. Note, that apply() also executes immediately.
const guptaKitchen = { name: "Gupta jis Kitchen" };
const guptaOrder = ["Chole kulche", "Punjabi Dhaba"];
console.log(cookDish.apply(guptaKitchen, guptaOrder));
----------------------------------------------------------------
OUTPUT:
Gupta jis Kitchen prepares Chole kulche in Punjabi Dhaba style!
Here, in .apply() everything is same the difference is how we are passing parameters of the function you can see that we are passing the function's parameter as an array not directly so that's the difference in .call() & .apply().
- bind(): This function also do the same, pass the reference of object to the function but the thing to note about .bind() is that it creates new function that function reference is stored in the variable where you call .bind(), and since we have reference of this function we can execute this function in future.
function reportDelivery(location, status) {
return `\({this.name} at \){location}: ${status}`;
}
const deliveryBoy = { name: "Ranveer" };
const bindReport = reportDelivery.bind(deliveryBoy,"Haridwar", "WHAT");
----------------------------------------------------------------
OUTPUT:
Ranveer at Haridwar: WHAT
Conclusion
At their core, call(), apply(), and bind() are about controlling execution context.
Mastering them means mastering how this behaves in JavaScript.
Whether you're borrowing methods, handling callbacks, or building scalable object structures, understanding these three methods gives you precise control over function invocation.
Once you truly understand how this works, JavaScript becomes far more predictable — and far more powerful.

