Skip to main content

Command Palette

Search for a command to run...

Understanding the this Keyword in JavaScript

Updated
β€’8 min read
Understanding the this Keyword in JavaScript
A
Web Developer

🧠 Think of this like:

πŸ‘‰ β€œWho is calling me?”

Not who created the function.
Not where it’s written.
πŸ‘‰ Only: who is calling it right now

🌍 1. this in Global Context

Example:

console.log(this);

What it means:

  • In browser β†’ this = window

  • In Node.js β†’ this = {} (module object)

Real-world analogy:

πŸ‘‰ You are standing alone, no one called you

➑️ So you represent the global environment

πŸ“¦ 2. this inside Object (Method)

Example:

const user = {
  name: "Ankita",
  greet: function () {
    console.log(this.name);
  }
};

user.greet();

Output:

Ankita

Why?

πŸ‘‰ user.greet() β†’ user is calling the function

➑️ So this = user

Real-world analogy:

πŸ‘© Ankita says:

"Hello, my name is Ankita"

πŸ‘‰ Here speaker = Ankita β†’ so this = Ankita


⚠️ 3. this inside normal function

Example:

function show() {
  console.log(this);
}

show();

Output:

  • Browser β†’ window

  • Strict mode β†’ undefined

Why?

πŸ‘‰ No object is calling it

➑️ So it falls back to global


Real-world analogy:

πŸ“’ Someone shouts in a room:

"Hello!"

πŸ‘‰ No one knows who said it

➑️ Default = β€œglobal person”


🎯 4. this inside object BUT function called separately

Example:

const user = {
  name: "Ankita",
  greet: function () {
    console.log(this.name);
  }
};

const fn = user.greet;
fn();

Output:

undefined

Why?

πŸ‘‰ fn() β†’ called WITHOUT object

➑️ So this = global


Real-world analogy:

πŸ‘© Ankita’s dialogue recorded:

Then someone else plays it:

"My name is Ankita"

πŸ‘‰ But speaker is now unknown

➑️ So this is lost


πŸ” 5. this depends on CALLER (MOST IMPORTANT)

Example:

function greet() {
  console.log(this.name);
}

const user1 = { name: "Ankita", greet };
const user2 = { name: "Rahul", greet };

user1.greet(); // Ankita
user2.greet(); // Rahul

Why?

πŸ‘‰ Same function

πŸ‘‰ Different caller

➑️ this changes dynamically


Real-world analogy:

🎀 Same mic, different speakers:

  • Ankita speaks β†’ "I am Ankita"

  • Rahul speaks β†’ "I am Rahul"

πŸ‘‰ Mic is same (function)

πŸ‘‰ Speaker changes (this)


πŸ”„ 6. How Calling Context Changes this

πŸ‘‰ THIS is the core concept

Case 1: Direct call

greet();

➑️ this = global


Case 2: Object call

user.greet();

➑️ this = user


Case 3: Assigned to variable

const fn = user.greet;
fn();

➑️ this = global


Case 4: Using call()

greet.call({ name: "Ankita" });

➑️ this = { name: "Ankita" }


Real-world analogy:

Think of call() like:

πŸ“ž You force someone to speak:

"Hey, say this as Ankita"


🧩 7. this inside Arrow Function (Important Difference)

Example:

const user = {
  name: "Ankita",
  greet: () => {
    console.log(this.name);
  }
};

user.greet();

Output:

undefined

Why?

πŸ‘‰ Arrow function DOES NOT have its own this

➑️ It takes from parent (global)


Real-world analogy:

πŸ‘Ά Child repeats parent’s identity:

β€œI am whoever my parent is”


🏒 Final Real-World Example (BEST FOR FRESHERS)

Scenario: Company Employees

const employee = {
  name: "Ankita",
  role: "Developer",
  introduce: function () {
    console.log(`Hi, I am \({this.name}, working as \){this.role}`);
  }
};

employee.introduce();

Case 1: Normal

employee.introduce();

➑️ "Hi, I am Ankita..."


Case 2: Borrow function

const emp2 = {
  name: "Rahul",
  role: "Tester"
};

emp2.introduce = employee.introduce;
emp2.introduce();

➑️ "Hi, I am Rahul..."


Case 3: Detached

const intro = employee.introduce;
intro();

➑️ ❌ Undefined


πŸ”₯ Final Rule (Remember This Always)

πŸ‘‰ this = object before dot (.)

Code this
user.greet() user
fn() global
obj.method() obj
call() custom object

⚑ 1. Nested Object + Function (Classic Confusion)

const user = {
  name: "Ankita",
  details: {
    age: 22,
    getAge: function () {
      console.log(this.age);
    }
  }
};

user.details.getAge();

βœ… Output:

22

Why?

πŸ‘‰ details.getAge() β†’ caller = details

➑️ this = details


❗ Now tricky version:

const fn = user.details.getAge;
fn();

❌ Output:

undefined

Why?

πŸ‘‰ Called without object

➑️ this = global


🧠 Real-world:

  • Inside company β†’ you are employee

  • Outside β†’ identity lost


⚑ 2. this lost inside callback (VERY IMPORTANT)

const user = {
  name: "Ankita",
  greet: function () {
    setTimeout(function () {
      console.log(this.name);
    }, 1000);
  }
};

user.greet();

❌ Output:

undefined

Why?

πŸ‘‰ setTimeout calls function

➑️ NOT user

➑️ So this = global


βœ… Fix using arrow function:

const user = {
  name: "Ankita",
  greet: function () {
    setTimeout(() => {
      console.log(this.name);
    }, 1000);
  }
};

user.greet();

βœ… Output:

Ankita

🧠 Real-world:

You tell your assistant:

"Remind them my name"

  • Normal function β†’ assistant forgets who you are

  • Arrow β†’ assistant remembers you


⚑ 3. Method Borrowing (Same function, different this)

function introduce() {
  console.log(`I am ${this.name}`);
}

const user1 = { name: "Ankita" };
const user2 = { name: "Rahul" };

user1.intro = introduce;
user2.intro = introduce;

user1.intro();
user2.intro();

βœ… Output:

I am Ankita
I am Rahul

🧠 Key Idea:

πŸ‘‰ Function same

πŸ‘‰ Caller changes β†’ this changes


⚑ 4. Chain Call (Important Interview Pattern)

const obj = {
  name: "Ankita",
  greet() {
    console.log(this.name);
    return this;
  }
};

obj.greet().greet();

βœ… Output:

Ankita
Ankita

Why?

πŸ‘‰ greet() returns this

➑️ So chaining keeps same object


🧠 Real-world:

Like:

"I speak β†’ I continue speaking β†’ still me"


⚑ 5. this inside class (Real Project Usage)

class User {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(this.name);
  }
}

const u1 = new User("Ankita");
u1.greet();

βœ… Output:

Ankita

❗ Problem:

const fn = u1.greet;
fn();

❌ Output:

undefined

βœ… Fix:

const fn = u1.greet.bind(u1);
fn();

🧠 Real-world:

You take employee out of company

➑️ They forget role

➑️ bind = attach identity permanently


⚑ 6. this in Event Listener (VERY REAL WORLD)

<button id="btn">Click</button>

<script>
document.getElementById("btn").addEventListener("click", function () {
  console.log(this);
});
</script>

βœ… Output:

πŸ‘‰ Button element


Why?

πŸ‘‰ Button is calling handler

➑️ this = button


❗ Arrow version:

document.getElementById("btn").addEventListener("click", () => {
  console.log(this);
});

❌ Output:

πŸ‘‰ window


🧠 Real-world:

  • Normal function β†’ button speaks

  • Arrow β†’ outer world speaks


⚑ 7. Object inside Function inside Object (Deep Confusion)

const user = {
  name: "Ankita",
  greet: function () {
    function inner() {
      console.log(this.name);
    }
    inner();
  }
};

user.greet();

❌ Output:

undefined

Why?

πŸ‘‰ inner() is normal function

➑️ Not called by user

➑️ this = global


βœ… Fix:

const user = {
  name: "Ankita",
  greet: function () {
    const inner = () => {
      console.log(this.name);
    };
    inner();
  }
};

⚑ 8. Trick Question (Interview Favorite)

const obj = {
  name: "Ankita",
  greet: function () {
    console.log(this.name);
  }
};

(obj.greet)();

βœ… Output:

Ankita

BUT:

(0, obj.greet)();

❌ Output:

undefined

Why?

πŸ‘‰ (0, obj.greet) removes object reference

➑️ becomes normal function call


πŸ”₯ FINAL MASTER RULE

πŸ‘‰ Ask ONLY ONE question:

❓ Who is calling the function?

That is your this.


🧠 Quick Cheat Sheet

Situation this
obj.method() obj
fn() global
setTimeout(fn) global
arrow fn parent this
event handler element
bind() fixed

βœ… One-Line Summary

πŸ‘‰ this is decided at runtime, based on who calls the function β€” not where it's written.