Confusion will be gone about 'this'

February 6, 2026·4 min read·By Md. Atiqur Rahman

cover
cover

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:

this is 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 modeglobalThis (window in a browser)
  • Strict modeundefined
'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 too

Fix 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#

CaseWhat 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 methodThe outer scope's this
Function inside a methodDefault — 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 email

Related Articles