Confusion will be gone about 'this'

Most confusion about this comes from one wrong assumption: that it's decided by where a function is written. It isn't. this is decided by how the function is called.
The rule in one sentence:
thisis whatever sits to the left of the dot at call time.
No dot? Then there's nothing to the left — and that's where the trouble starts. Here are five cases that cover it.
1. A plain function call
function show() {
console.log(this);
}
show();There's no dot, so nothing is to the left. JavaScript falls back to a default:
- Non-strict mode →
globalThis(windowin a browser) - Strict mode →
undefined
'use strict';
function show() {
console.log(this); // undefined
}
show();Know both answers. The strict-mode undefined is actually the friendlier one — you get a loud error instead of silently writing properties onto the global object. ES modules and class bodies are always strict, so in modern code undefined is what you'll usually see.
2. Detach a method and this is gone
const user = {
name: 'Atiq',
greet() {
console.log(this.name);
}
};
const fn = user.greet;
fn();Logs undefined — or throws a TypeError in strict mode.
The reason is the same as case 1: fn() has no dot. Writing user.greet copies a reference to the function; it does not drag user along with it. The function object and its "owner" are separate things.
This is the single most common this bug in the wild:
setTimeout(user.greet, 100); // this is lost
button.addEventListener('click', user.greet); // lost here tooFix it by binding, or by calling through a wrapper:
setTimeout(user.greet.bind(user), 100);
setTimeout(() => user.greet(), 100);3. Nested objects — only the last dot counts
const a = {
name: 'A',
b: {
name: 'B',
show() {
console.log(this.name);
}
}
};
a.b.show();Logs B.
People often assume the whole chain somehow feeds into this. It doesn't. Only the thing immediately left of the rightmost dot matters — here, a.b. The outer a is irrelevant; it was just the path used to reach b.
4. An arrow function used as a method
const obj = {
name: 'Atiq',
greet: () => {
console.log(this.name);
}
};
obj.greet();Logs undefined — the obj. part bought us nothing.
Arrow functions have no this of their own. They borrow it from the scope where they were written. An object literal doesn't create a scope, so this resolves all the way out to the module or file top level, where it's undefined or window.
The takeaway: use shorthand method syntax for methods, not arrows.
const obj = {
name: 'Atiq',
greet() { // ✅ this works as expected
console.log(this.name);
}
};5. A regular function nested inside a method
const obj = {
name: 'Atiq',
greet() {
function inner() {
console.log(this.name);
}
inner();
}
};
obj.greet();Logs undefined (TypeError in strict mode).
greet does have the right this — it's obj. But inner() is a separate function call with no dot in front of it, so its own this falls back to the default from case 1. this is not inherited by nested functions.
The old workaround was to capture it manually:
greet() {
const self = this;
function inner() {
console.log(self.name);
}
inner();
}An arrow function does the same thing for free — and this is exactly what arrows are good for:
greet() {
const inner = () => {
console.log(this.name); // borrows greet's this
};
inner();
}Recap
| Case | What this becomes |
|---|---|
show() | undefined (strict) / globalThis |
const fn = obj.m; fn() | Lost — no dot |
a.b.show() | a.b — only the last dot counts |
| Arrow as a method | The outer scope's this |
| Function inside a method | Default — not inherited |
Notice the pattern? Every "broken" case is one where the dot is missing at the moment of the call. So when you're debugging, go to the line where the function is actually invoked and ask: what's to the left of the dot right here? The answer is almost always sitting right there.
Two rules of thumb worth memorizing:
- Writing a method on an object or class → regular function
- Writing a callback inside one → arrow function
Working on something similar? Get in touch
Have questions about this article, architecture patterns, or looking for pair programming and engineering consulting? My inbox is always open.
Send me an emailRelated Articles
how 'this' behaves in the call, bind, apply
**a brief intro of this with call, bind and apply**
What Really Happens When You Call setTimeout()?
A Deep Dive from JavaScript to Hardware Every JavaScript developer has used setTimeout. It's one of the first async concepts we learn. But have you ever won...
Understanding React’s Virtual DOM: The Secret Behind Lightning-Fast UIs
How React updates your apps in milliseconds, not seconds The Problem: Why DOM Updates Are Slow Imagine you’re building a social media feed. Every like, comment,...