Understanding this in JavaScript

Search for a command to run...

No comments yet. Be the first to comment.
Picture this: you're writing a program to store the marks of five students. Without arrays, you'd probably do something like this: let marks1 = 88; let marks2 = 74; let marks3 = 91; let marks4 = 65; l
Introduction If you've ever built something with vanilla JavaScript and had to update the UI frequently, you already know the pain. You call document.getElementById, change some text, update a class,
Introduction If you've ever installed and tried out Linux after seeing a cool hacking sequence in a sci-fi movie, you know that opening it feels like stepping into a strange city with many roads named

Introduction JavaScript gives you objects and arrays out of the box, and for a long time those two were the default answer to almost every data storage problem. Objects for key-value pairs, arrays for

Introduction Most JavaScript codebases are full of code like this: const user = { name: "Sara", age: 28, city: "Mumbai" }; const name = user.name; const age = user.age; const city = user.city; Three

Most JavaScript confusion around this comes from one wrong assumption: that this depends on where a function is defined. It doesn't. It depends on who called the function.
That one shift in thinking makes most of the confusion go away.
this Actually isthis is a reference to the calling context of a function. When a function runs, JavaScript looks at what triggered the call and sets this to that thing.
Not where the function lives in your file. Not which object it belongs to in your source code. Who called it at runtime.
this in the Global ContextWhen you call a plain function with nothing owning it, this falls back to the global object.
function greet() {
console.log(this);
}
greet();
In a browser, that logs window. In Node.js, it's global. In strict mode, it's undefined.
Nobody specific called it, so JavaScript picks the default.
this Inside an ObjectThis is where this starts being useful.
const person = {
name: 'Alice',
greet: function () {
console.log("Hi, I'm " + this.name);
}
};
person.greet(); // Hi, I'm Alice
person is calling greet, so this is person. That's it.
thisHere's the part that trips people up. Take the exact same function from above and pull it out of the object:
const greet = person.greet;
greet(); // Hi, I'm undefined
Same function. Different caller. Now nobody owns the call, this falls back to the global object, and name isn't defined there.
This is the source of most this bugs. The function didn't change. The calling context did.
this Inside Nested FunctionsThe problem compounds when you have a function inside a method.
const person = {
name: 'Alice',
greet: function () {
function inner() {
console.log(this.name); // undefined
}
inner();
}
};
person.greet();
greet is called by person, so this inside greet is person. But inner is called as a plain function with no owner, so this resets to the global object.
A common fix is to capture this before going in:
const person = {
name: 'Alice',
greet: function () {
const self = this;
function inner() {
console.log(self.name); // Alice
}
inner();
}
};
Or just use an arrow function, which doesn't have its own this and inherits from the surrounding scope:
const person = {
name: 'Alice',
greet: function () {
const inner = () => {
console.log(this.name); // Alice
};
inner();
}
};
thisArrow functions inherit this from wherever they were defined, and nothing can change that.
const person = {
name: 'Alice',
greet: () => {
console.log(this.name); // undefined, always
}
};
person.greet();
Even though greet is on person, it's an arrow function. this here is whatever this was in the outer scope when the object was created, not person. Arrow functions are great in a lot of situations, but if you need this to refer to the object, use a regular function.
Where this appears |
What it refers to |
|---|---|
| Global function call | Global object (or undefined in strict mode) |
| Object method call | The object before the dot |
| Nested plain function | Global object (loses the outer this) |
| Arrow function | Inherited from surrounding scope |
Once you internalize "who called this function," most this surprises stop being surprises. The function is the same. The caller is what changes.