this keyword of javascript actually confuse a lots of junior and senior developer. So let me explain in the easist way possible.
this behavior doen't depend upon where this is used but from where it is called. Understand this by a example.
Example:
let obj={
name:"Kush",
displayName(){
console.log(`My name is ${this.name}`);
}
}
Now, when obj.displayName() is called we get output as :
// My name is Kush.
But what if i change this to something like this :
let person=obj.displayName;
person();
Now the output will be :
// My name is undefined.
So, this show us that the execution of this is more important then the place where this is defined.
In non strict mode, this point to the global window object in browser and can be different in other runtimes.
In strict mode, this point to the undefined.
Arrow function: Arrow functions do not have their own this; they capture this from their lexical scope (where they were created).
let obj={
name:"Kush",
personName:()=>{
console.log(`My name is ${this.name}`)
}
}
Now obj.personName() // My name is undefined
Understanding this with Rules
Before jumping into more examples, it's helpful to remember that this in JavaScript follows a few binding rules. The rule that applies depends on how a function is called.
There are four main rules:
Default Binding
Implicit Binding
Explicit Binding
Arrow Function (Lexical Binding)
Let's understand them one by one.
- Default Binding When a regular function is called without any object, this follows the default binding rule.
function show() {
console.log(this);
}
show();
In a browser (non-strict mode):
this → window object
In strict mode:
this → undefined
This happens because the function was not called through an object.
- Implicit Binding
When a function is called as a method of an object, this refers to that object.
const user = {
name: "Kush",
greet() {
console.log(this.name);
}
};
user.greet();
Output:
Kush
Here the object before the dot (user) becomes this.
- Losing Implicit Binding
A very common mistake developers make is losing the reference of the object.
const user = {
name: "Kush",
greet() {
console.log(this.name);
}
};
const greetFn = user.greet;
greetFn();
Output: undefined
Why? Because now the function is called like this:
greetFn()
There is no object before the function call, so default binding applies.
- Explicit Binding (call, apply, bind)
JavaScript allows us to explicitly decide what this should be.
const user1 = { name: "Kush" };
const user2 = { name: "Rahul" };
function greet() {
console.log(this.name);
}
greet.call(user1);
greet.call(user2);
Output:
Kush
Rahul
Here we are manually setting this using call.
- Arrow Function this (Lexical Binding) Arrow functions behave differently.
They do not have their own this. Instead, they inherit this from the surrounding scope.
const user = {
name: "Kush",
greet: () => {
console.log(this.name);
}
};
user.greet();
Output: undefined
Why? Because the arrow function takes this from the outer scope, which in this case is the global scope, not the object.
Correct Use of Arrow Function
Arrow functions work well when used inside another method.
const user = {
name: "Kush",
greet() {
const say = () => {
console.log(this.name);
};
say();
}
};
user.greet();
Output:
Kush
Here the arrow function inherits this from greet(), which is user.
Another Common Example (setTimeout)
Many developers get confused in asynchronous callbacks.
const user = {
name: "Kush",
greet() {
setTimeout(function () {
console.log(this.name);
}, 1000);
}
};
user.greet();
Output: undefined
Because the callback is a regular function, so this becomes the global object.
Fix with Arrow Function
const user = {
name: "Kush",
greet() {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
user.greet();
Output:
Kush
So, I hope this must clear some concept of this. Now let's make this further clear with some example. Now guss the ouput and you can comment on this article if any example still confuse you.
1) const user = {
name: "Kush",
greet() {
setTimeout(function () {
console.log(this.name);
}, 0);
}
};
user.greet();
2) const user = {
name: "Kush",
greet() {
setTimeout(() => {
console.log(this.name);
}, 0);
}
};
user.greet();
3) const user1 = {
name: "Kush"
};
const user2 = {
name: "Rahul"
};
function greet() {
console.log(this.name);
}
greet.call(user1);
greet.call(user2);
4) const user = {
name: "Kush"
};
const greet = () => {
console.log(this.name);
};
greet.call(user);
5) const user = {
name: "Kush",
address: {
name: "Delhi",
greet() {
console.log(this.name);
}
}
};
user.address.greet();
6) const user1 = {
name: "Kush",
greet() {
console.log(this.name);
}
};
const user2 = {
name: "Rahul"
};
user2.greet = user1.greet;
user2.greet();
7) const user = {
name: "Kush",
greet() {
return function () {
console.log(this.name);
};
}
};
user.greet()();
If you guess all question right , you are on a right track!
Top comments (0)