this KeywordThe this keyword is one of the most important—and often confusing—concepts in JavaScript.
this refers to the object that is executing the current function.
Important: The value of
thisdepends on how a function is called, not where it is defined.
Understanding this is essential because it is widely used in:
this?Think of this as asking:
"Who is calling this function?"
Example
const user = {
name: "Samir",
greet() {
console.log(this.name);
}
};
user.greet();
Output
Samir
Here,
this
↓
user object
this Important?The this keyword allows the same function to work with different objects.
It is heavily used in:
this in Different ContextsThe value of this changes depending on how the function is called.
call()apply()bind()this in the Global ContextIn a browser:
console.log(this);
Output
window
Why?
Because the global object in browsers is:
window
this Inside Object MethodsA method is simply a function inside an object.
const user = {
name: "Samir",
greet() {
console.log(this.name);
}
};
user.greet();
Output
Samir
user.greet()
↓
this = user
const car = {
brand: "Toyota",
showBrand() {
console.log(this.brand);
}
};
car.showBrand();
Output
Toyota
this in Regular FunctionsRegular functions behave differently.
function greet() {
console.log(this);
}
greet();
Output
window
"use strict";
function greet() {
console.log(this);
}
greet();
Output
undefined
function showName() {
console.log(this.name);
}
showName();
Output
undefined
Why?
Because no object called the function.
this Inside Nested Functionsconst user = {
name: "Samir",
greet() {
function inner() {
console.log(this);
}
inner();
}
};
user.greet();
Output
window
or
undefined
(in strict mode)
Why?
Because inner() is called like a normal function.
this in Arrow FunctionsArrow functions do not create their own this.
Instead, they inherit this from the surrounding scope.
const user = {
name: "Samir",
greet() {
const inner = () => {
console.log(this.name);
};
inner();
}
};
user.greet();
Output
Samir
greet()
↓
this = user
↓
Arrow Function
↓
Uses Same this
const user = {
name: "Samir",
greet() {
function test() {
console.log(this);
}
test();
}
};
Output
window
or
undefined
const user = {
name: "Samir",
greet() {
const test = () => {
console.log(this);
};
test();
}
};
Output
user object
this in Event HandlersWhen using DOM events, this refers to the element that triggered the event.
HTML
<button id="btn">
Click Me
</button>
JavaScript
const btn =
document.getElementById("btn");
btn.addEventListener(
"click",
function () {
console.log(this);
}
);
Output
<button>
The clicked button becomes this.
btn.addEventListener(
"click",
() => {
console.log(this);
}
);
Output
window
(or the surrounding lexical scope)
Why?
Arrow functions inherit this instead of creating their own.
JavaScript lets us manually decide what this should be.
This is done using:
call()apply()bind()call()call() immediately executes a function with a custom this.
functionName.call(
object,
arg1,
arg2
);
function greet() {
console.log(this.name);
}
const user = {
name: "Samir"
};
greet.call(user);
Output
Samir
call()
↓
this = user
call() with Argumentsfunction greet(city) {
console.log(
this.name,
city
);
}
const user = {
name: "Samir"
};
greet.call(
user,
"Jhapa"
);
Output
Samir Jhapa
apply()apply() works like call().
The difference is that arguments are passed as an array.
functionName.apply(
object,
[arg1, arg2]
);
function greet(city) {
console.log(
this.name,
city
);
}
const user = {
name: "Samir"
};
greet.apply(
user,
["Jhapa"]
);
Output
Samir Jhapa
call() vs apply()Using call()
greet.call(
user,
"Jhapa",
"Nepal"
);
Using apply()
greet.apply(
user,
[
"Jhapa",
"Nepal"
]
);
bind()Unlike call() and apply():
const newFunction =
functionName.bind(
object
);
function greet() {
console.log(this.name);
}
const user = {
name: "Samir"
};
const boundFunction =
greet.bind(user);
Execute later
boundFunction();
Output
Samir
bind()?bind() is useful when passing object methods around.
const user = {
name: "Samir",
greet() {
console.log(this.name);
}
};
const fn =
user.greet;
fn();
Output
undefined
Fix using bind()
const fn =
user.greet.bind(user);
fn();
Output
Samir
const button = {
label: "Save",
click() {
console.log(this.label);
}
};
Without bind()
setTimeout(
button.click,
1000
);
Output
undefined
With bind()
setTimeout(
button.click.bind(button),
1000
);
Output
Save
| Context | Value of this |
|---|---|
| Global Scope (Browser) | window |
| Object Method | Calling Object |
| Regular Function | window / undefined |
| Arrow Function | Inherited from parent |
| Event Handler | Triggered Element |
call() |
Explicitly Set |
apply() |
Explicitly Set |
bind() |
Permanently Bound |
call() vs apply() vs bind()| Method | Executes Immediately | Arguments |
|---|---|---|
call() |
Yes | Separate Values |
apply() |
Yes | Array |
bind() |
No | Separate Values |
const user = {
name: "Samir",
greet: () => {
console.log(this.name);
}
};
user.greet();
Output
undefined
Why?
Because arrow functions do not have their own this.
They inherit this from the surrounding scope, which is not the user object.
Good
const user = {
greet() {
console.log(this);
}
};
const numbers = [
1,
2,
3
];
numbers.map(
num => num * 2
);
Avoid
const user = {
greet: () => {
}
};
Prefer
const user = {
greet() {
}
};
bind() When Passing Methodsbutton.click.bind(button);
This prevents losing the correct this value.
| Concept | Purpose |
|---|---|
this |
Current execution context |
| Object Method | this = object |
| Regular Function | this = window / undefined |
| Arrow Function | Inherits parent this |
| Event Handler | this = HTML element |
call() |
Execute with custom this |
apply() |
Execute with custom this and array arguments |
bind() |
Create a new function with permanently bound this |
The value of this depends entirely on how a function is called, not where it is defined.
Object Method
↓
this = Object
Regular Function
↓
this = window / undefined
Arrow Function
↓
Uses Parent this
Event Handler
↓
this = Element
call / apply / bind
↓
Manually Control this
Understanding this is essential because JavaScript classes, React class components, event handlers, callbacks, timers, and many libraries rely heavily on correct this behavior. Mastering this concept will help you avoid some of the most common JavaScript bugs.