Understanding this in JavaScript: A Complete Guide with Examples

The this
keyword in JavaScript is one of the most misunderstood concepts, yet it's fundamental to writing effective code. It refers to the execution context and behaves differently depending on how a function is called.
In this article, you'll learn:
✔️ What this
refers to in different contexts.
✔️ Key rules governing this
.
✔️ Practical examples to solidify your understanding.
What is this
?
this
is a special keyword that points to an object—the one currently executing the code. Its value depends entirely on how a function is called, not where it's defined.
Rules of this
in JavaScript (The 5 Key Scenarios)
Here are the five most common scenarios where this
behaves differently:
1. Default Binding (Global or undefined
in Strict Mode)
When used in a regular function (not an object method or event),
this
refers to:window
(in browsers) in non-strict mode.undefined
in strict mode.
Example (Non-strict mode):
function sayHello() {
console.log(this); // window (global object in browser)
}
sayHello();
Example (Strict mode):
"use strict";
function sayHello() {
console.log(this); // undefined
}
sayHello();
2. Implicit Binding (this
in Object Methods)
- When a function is called as a method of an object,
this
refers to the object itself.
Example:
const user = {
name: "Alice",
greet() {
console.log(`Hello, ${this.name}!`); // `this` = user
},
};
user.greet(); // "Hello, Alice!"
⚠️ Pitfall: If you extract the method (e.g., const greetFunc = user.greet
), this
may get lost!
❓ What’s wrong?
You saved the function to a new variable
greetFunc
Now you're calling it without an object, so it's just a plain function call
In strict mode,
this
becomesundefined
In non-strict mode,
this
becomes the global object (window
in browsers)SO this line console.log(
Hello, ${
this.name
}!
);Will try to access: undefined.name → causes error or prints "Hello, undefined!"
How to fix this: const greetFunc = user.greet.bind(user); greetFunc(); // "Hello, Alice!"
3. Explicit Binding (Forcing this
with call
, apply
, bind
)
You can force what
this
refers to using:func.call
(obj, args)
→ Callsfunc
withobj
asthis
.func.apply(obj, [args])
→ Same ascall
but takes an array of args.func.bind(obj)
→ Returns a new function permanently bound toobj
.
Example (call
and apply
):
function introduce(lang) {
console.log(`${this.name} codes in ${lang}.`);
}
const dev = { name: "Bob" };
introduce.call(dev, "JavaScript"); // "Bob codes in JavaScript."
introduce.apply(dev, ["Python"]); // "Bob codes in Python."
Example (bind
):
const boundFunc = introduce.bind(dev, "TypeScript");
boundFunc(); // "Bob codes in TypeScript."
4. new
Binding (this
in Constructor Functions & Classes)
- When a function is called with
new
,this
refers to the newly created instance.
Example (Constructor Function):
function Person(name) {
this.name = name;
console.log(this); // Person { name: "Charlie" }
}
const person = new Person("Charlie");
Example (Class Syntax):
class User {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hi, I'm ${this.name}.`);
}
}
const user = new User("Dana");
user.greet(); // "Hi, I'm Dana."
5. Arrow Functions (Lexical this
)
Unlike normal functions, arrow functions don’t have their own
this
.They inherit
this
from their parent scope.
Example:
const obj = {
name: "Eve",
greet: () => {
console.log(`Hi from ${this.name}.`); // `this` ≠ obj!
}
};
obj.greet(); // "Hi from undefined." (inherits global/undefined `this`)
✅ Good Use Case for Arrow Functions (Event Handlers):
class Button {
constructor() {
this.button = document.querySelector("button");
this.button.addEventListener("click", () => {
console.log(this); // `this` = Button instance
});
}
}
Common Pitfalls & Fixes
Problem: Losing this
in Callbacks
const user = {
name: "Frank",
greet() {
setTimeout(function() {
console.log(`Hello, ${this.name}!`); // `this` = window/undefined
}, 1000);
}
};
user.greet(); // "Hello, !"
✅ Fix: Use an arrow function to preserve this
:
setTimeout(() => {
console.log(`Hello, ${this.name}!`); // `this` = user (lexically bound)
}, 1000);
or bind:
setTimeout(function() {
console.log(`Hello, ${this.name}!`);
}.bind(user), 1000);
Summary of this
Rules
Scenario | What this refers to |
Default Binding | window (non-strict) / undefined (strict) |
Method Call (obj.func() ) | The object (obj ) |
Explicit Binding (call , apply , bind ) | The provided object (obj ) |
new Binding (new Class() ) | The newly created instance |
Arrow Functions | Inherited from parent scope |
Final Thoughts
The this
keyword is context-dependent, but once you understand the core rules, it becomes easy to predict. Key takeaways:
☑️ Use
call
/apply
/bind
for explicit control.☑️ Arrow functions inherit
this
(=>
≠function
).☑️
new
creates a newthis
object.
Subscribe to my newsletter
Read articles from pushpesh kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
