<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Understanding the this Keyword in JavaScript]]></title><description><![CDATA[Understanding the this Keyword in JavaScript]]></description><link>https://understanding-this-keyword-in-js.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>Understanding the this Keyword in JavaScript</title><link>https://understanding-this-keyword-in-js.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 24 Jun 2026 17:25:43 GMT</lastBuildDate><atom:link href="https://understanding-this-keyword-in-js.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Understanding this in JavaScript: Who Is Calling?]]></title><description><![CDATA[Who is this for? If this in JavaScript has ever confused you — sometimes it is the object, sometimes it is the window, sometimes it is undefined — this guide breaks it down simply using one core idea ]]></description><link>https://understanding-this-keyword-in-js.hashnode.dev/understanding-this-in-javascript-who-is-calling</link><guid isPermaLink="true">https://understanding-this-keyword-in-js.hashnode.dev/understanding-this-in-javascript-who-is-calling</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[chaicode webdev cohort 2026]]></category><category><![CDATA[chai-code ]]></category><category><![CDATA[this keyword]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[ABHISHEK KUMAR]]></dc:creator><pubDate>Fri, 01 May 2026 07:31:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6784893ff404b926e9fe3b72/e8d4dfeb-ae61-4af5-8e9e-b03e3236d023.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><strong>Who is this for?</strong> If <code>this</code> in JavaScript has ever confused you — sometimes it is the object, sometimes it is the window, sometimes it is undefined — this guide breaks it down simply using one core idea that makes everything click.</p>
</blockquote>
<hr />
<h2>Table of Contents</h2>
<ol>
<li><p><a href="#1-what-does-this-represent">What Does <code>this</code> Represent?</a></p>
</li>
<li><p><a href="#2-this-in-the-global-context"><code>this</code> in the Global Context</a></p>
</li>
<li><p><a href="#3-this-inside-objects"><code>this</code> Inside Objects</a></p>
</li>
<li><p><a href="#4-this-inside-functions"><code>this</code> Inside Functions</a></p>
</li>
<li><p><a href="#5-how-calling-context-changes-this">How Calling Context Changes <code>this</code></a></p>
</li>
<li><p><a href="#diagrams">Diagrams</a></p>
</li>
<li><p><a href="#quick-reference">Quick Reference</a></p>
</li>
</ol>
<hr />
<h2>Introduction</h2>
<p><code>this</code> is one of the most misunderstood keywords in JavaScript. Most beginners assume it works like in other languages — a fixed reference to "the current object." In JavaScript, <code>this</code> is different. Its value is not set when you write the code. It is set <strong>when the function is called</strong>.</p>
<p>The single most important idea in this entire article:</p>
<blockquote>
<p><code>this</code> <strong>refers to whoever is calling the function at that moment.</strong></p>
</blockquote>
<p>Hold that thought. Everything you learn in this guide flows from it.</p>
<blockquote>
<p>💡 <strong>Open your browser console</strong> (<code>F12</code> → Console tab) and try every example as you read.</p>
</blockquote>
<hr />
<h2>1. What Does <code>this</code> Represent?</h2>
<p><code>this</code> is a special keyword that automatically refers to an <strong>object</strong> — specifically, the object that is responsible for the current function call.</p>
<p>Think of it like this: when a function runs, JavaScript looks around and asks <em>"Who triggered this call?"</em> Whatever the answer is — that is <code>this</code>.</p>
<h3>A human analogy</h3>
<p>Imagine you receive a letter that says: <em>"My phone number is 98765."</em> The word <em>"My"</em> only makes sense if you know who wrote the letter. If Priya wrote it, "My" means Priya. If Rahul wrote it, "My" means Rahul.</p>
<p><code>this</code> works the same way. The word <code>this</code> inside a function only has a specific meaning once you know <strong>who called that function</strong>.</p>
<pre><code class="language-javascript">const priya = {
  name: "Priya",
  greet: function() {
    console.log("Hello, I am " + this.name);
    //                           ↑
    //               this = whoever called greet()
  }
};

priya.greet(); // "Hello, I am Priya"
//  ↑
// priya called greet() — so this = priya
</code></pre>
<p><code>priya</code> is the caller. So <code>this</code> inside <code>greet</code> is <code>priya</code>. Therefore <code>this.name</code> is <code>"Priya"</code>.</p>
<hr />
<h2>2. <code>this</code> in the Global Context</h2>
<p>When code runs outside any function or object — at the top level of your script — <code>this</code> refers to the <strong>global object</strong>.</p>
<ul>
<li><p>In a <strong>browser</strong>, the global object is <code>window</code></p>
</li>
<li><p>In <strong>Node.js</strong>, the global object is <code>global</code></p>
</li>
</ul>
<pre><code class="language-javascript">// In the browser — at the top level
console.log(this);          // Window {...}
console.log(this === window); // true
</code></pre>
<h3>Global variables become properties of <code>this</code></h3>
<p>When you declare a variable with <code>var</code> at the top level (not inside a function or block), it becomes a property of the global object:</p>
<pre><code class="language-javascript">var appName = "MyApp";

console.log(window.appName); // "MyApp"
console.log(this.appName);   // "MyApp"
</code></pre>
<blockquote>
<p>⚠️ This is one reason <code>var</code> is discouraged in modern code — it pollutes the global object. Variables declared with <code>let</code> and <code>const</code> do <strong>not</strong> become properties of <code>this</code>.</p>
</blockquote>
<pre><code class="language-javascript">let siteName = "MyBlog";
console.log(this.siteName);   // undefined — let does not attach to global
console.log(window.siteName); // undefined
</code></pre>
<h3><code>this</code> in the global context — summary</h3>
<pre><code class="language-javascript">// Browser — top-level code
console.log(this);            // Window
console.log(this === window); // true

// Node.js — top-level code
console.log(this);            // {}  (the module's exports object)
console.log(this === global); // false at the top level in modules
</code></pre>
<p>In practice, you rarely use <code>this</code> at the global level intentionally. The important contexts are inside objects and functions — which we cover next.</p>
<hr />
<h2>3. <code>this</code> Inside Objects</h2>
<p>When a function is defined as a <strong>method</strong> of an object (a property that holds a function), and you call that method using the object, <code>this</code> inside that method refers to the <strong>object itself</strong>.</p>
<h3>Basic object method</h3>
<pre><code class="language-javascript">const user = {
  name:  "Priya",
  email: "priya@example.com",
  greet: function() {
    console.log("Hi, I am " + this.name);
    console.log("Reach me at " + this.email);
  }
};

user.greet();
// Hi, I am Priya
// Reach me at priya@example.com
</code></pre>
<p><code>user.greet()</code> — <code>user</code> is the caller. So <code>this</code> = <code>user</code>. And <code>this.name</code> = <code>user.name</code> = <code>"Priya"</code>.</p>
<h3>Accessing multiple properties with <code>this</code></h3>
<pre><code class="language-javascript">const product = {
  name:     "Laptop",
  price:    75000,
  discount: 0.10,

  getFinalPrice: function() {
    const saving   = this.price * this.discount;
    const finalPrice = this.price - saving;
    return finalPrice;
  },

  describe: function() {
    console.log(this.name + " costs ₹" + this.getFinalPrice());
  }
};

console.log(product.getFinalPrice()); // 67500
product.describe();                   // Laptop costs ₹67500
</code></pre>
<p>Every property and method of <code>product</code> is accessible via <code>this</code> inside any of its methods — because <code>product</code> is the caller.</p>
<h3>Multiple objects, same method shape</h3>
<pre><code class="language-javascript">const student1 = {
  name:   "Priya",
  course: "Computer Science",
  introduce: function() {
    console.log("I am " + this.name + ", studying " + this.course);
  }
};

const student2 = {
  name:   "Rahul",
  course: "Mathematics",
  introduce: function() {
    console.log("I am " + this.name + ", studying " + this.course);
  }
};

student1.introduce(); // I am Priya, studying Computer Science
student2.introduce(); // I am Rahul, studying Mathematics
</code></pre>
<p>Even though the <code>introduce</code> function body is identical in both objects, <code>this</code> gives the right result each time — because <code>this</code> is set by <strong>who calls the function</strong>, not by where the function was written.</p>
<h3>Nested objects</h3>
<p>When a method is on a nested object, <code>this</code> refers to the <strong>immediately containing object</strong> — the direct caller:</p>
<pre><code class="language-javascript">const company = {
  name: "TechCorp",
  ceo: {
    name: "Ananya",
    introduce: function() {
      console.log("I am " + this.name + ", CEO.");
      // this = company.ceo (the direct caller), NOT company
    }
  }
};

company.ceo.introduce(); // I am Ananya, CEO.
</code></pre>
<p><code>this</code> is <code>company.ceo</code> — not <code>company</code> — because <code>ceo</code> is the object that directly owns <code>introduce</code>.</p>
<hr />
<h2>4. <code>this</code> Inside Functions</h2>
<p>This is where <code>this</code> starts to feel tricky. The behaviour depends on <strong>how</strong> the function is called — not where it was defined.</p>
<h3>Regular function called without an object — <code>this</code> is global (or undefined)</h3>
<p>When you call a plain function — not attached to any object — <code>this</code> becomes the global object in non-strict mode, or <code>undefined</code> in strict mode.</p>
<pre><code class="language-javascript">function showThis() {
  console.log(this);
}

showThis(); // Window {...}  (browser, non-strict mode)
</code></pre>
<p>There is no object before the function call — no <code>something.showThis()</code> — so JavaScript falls back to the global object.</p>
<h3>Strict mode — <code>this</code> becomes <code>undefined</code></h3>
<pre><code class="language-javascript">"use strict";

function showThis() {
  console.log(this); // undefined — strict mode prevents the global fallback
}

showThis();
</code></pre>
<p>Strict mode is a safer way to write JavaScript — the <code>undefined</code> result makes accidental global pollution easier to catch as an error.</p>
<h3>The lost <code>this</code> problem — a very common mistake</h3>
<pre><code class="language-javascript">const timer = {
  message: "Time is up!",
  start: function() {
    setTimeout(function() {
      console.log(this.message); // undefined — `this` is lost here!
    }, 1000);
  }
};

timer.start();
</code></pre>
<p><strong>Why did this fail?</strong></p>
<p><code>timer.start()</code> is called on <code>timer</code>, so <code>this = timer</code> inside <code>start</code>. But <code>setTimeout</code> calls its callback as a plain function — <strong>not as a method of</strong> <code>timer</code>. By the time the callback runs, there is no object calling it, so <code>this</code> defaults back to <code>window</code> (or <code>undefined</code> in strict mode). <code>window.message</code> does not exist.</p>
<p>This is the most common <code>this</code>-related bug in JavaScript.</p>
<h3>The fix — use an arrow function</h3>
<p>Arrow functions do not have their own <code>this</code>. They <strong>inherit</strong> <code>this</code> <strong>from the surrounding code</strong> where they were written — which is called the lexical scope.</p>
<pre><code class="language-javascript">const timer = {
  message: "Time is up!",
  start: function() {
    // Arrow function — this is inherited from start(), where this = timer
    setTimeout(() =&gt; {
      console.log(this.message); // "Time is up!" ✓
    }, 1000);
  }
};

timer.start(); // "Time is up!" (after 1 second)
</code></pre>
<p>The arrow function inside <code>setTimeout</code> does not create a new <code>this</code> — it borrows <code>this</code> from <code>start</code>, where <code>this</code> is <code>timer</code>. Problem solved.</p>
<h3>Regular function vs arrow function — <code>this</code> behaviour</h3>
<pre><code class="language-javascript">const obj = {
  value: 42,

  // Regular method — has its own `this` (= obj when called as obj.method)
  regularMethod: function() {
    console.log("Regular:", this.value); // 42
  },

  // Arrow method — inherits `this` from where the object is defined
  arrowMethod: () =&gt; {
    console.log("Arrow:", this.value);   // undefined
    // `this` here is the global object, not obj
    // because arrows inherit from the enclosing lexical scope
  }
};

obj.regularMethod(); // Regular: 42
obj.arrowMethod();   // Arrow:   undefined
</code></pre>
<blockquote>
<p>🔑 <strong>Key rule:</strong> Do not use arrow functions as object methods when you need <code>this</code> to refer to the object. Use regular functions for methods. Use arrow functions for <strong>callbacks inside methods</strong>.</p>
</blockquote>
<hr />
<h2>5. How Calling Context Changes <code>this</code></h2>
<p>The same function can produce completely different values of <code>this</code> depending on how it is called. Let us look at all the ways <code>this</code> can shift.</p>
<h3>Same function, three different callers</h3>
<pre><code class="language-javascript">function introduce() {
  console.log("Hello, I am " + this.name);
}

const person1 = { name: "Priya",  introduce: introduce };
const person2 = { name: "Rahul",  introduce: introduce };
const person3 = { name: "Ananya", introduce: introduce };

person1.introduce(); // Hello, I am Priya
person2.introduce(); // Hello, I am Rahul
person3.introduce(); // Hello, I am Ananya

introduce();         // Hello, I am undefined (or window.name in browser)
</code></pre>
<p>The exact same function produces four different results — all because of who called it.</p>
<h3><code>call()</code> — call with a specific <code>this</code></h3>
<p><code>call()</code> lets you invoke a function and manually set what <code>this</code> should be:</p>
<pre><code class="language-javascript">function greet(greeting) {
  console.log(greeting + ", I am " + this.name + " from " + this.city);
}

const person = { name: "Priya", city: "Mumbai" };

greet.call(person, "Hello");
// Hello, I am Priya from Mumbai
// ↑ this = person, "Hello" is the argument
</code></pre>
<h3><code>apply()</code> — like <code>call()</code> but arguments as an array</h3>
<pre><code class="language-javascript">greet.apply(person, ["Namaste"]);
// Namaste, I am Priya from Mumbai
// ↑ same as call, but arguments passed as an array
</code></pre>
<h3><code>bind()</code> — create a new function with <code>this</code> permanently fixed</h3>
<p><code>bind()</code> does not call the function immediately. It returns a <strong>new function</strong> where <code>this</code> is permanently locked to the object you specify:</p>
<pre><code class="language-javascript">function greet() {
  console.log("Hi, I am " + this.name);
}

const person = { name: "Priya" };

const boundGreet = greet.bind(person); // create a new function, this = person

boundGreet(); // Hi, I am Priya — this is always person, no matter how you call it
</code></pre>
<p><code>bind</code> is useful when you need to pass a method as a callback but want to preserve its <code>this</code>:</p>
<pre><code class="language-javascript">const user = {
  name: "Rahul",
  greet: function() {
    console.log("Hello from " + this.name);
  }
};

// Without bind — this is lost when passed as a callback
setTimeout(user.greet, 1000);         // Hello from undefined

// With bind — this is preserved
setTimeout(user.greet.bind(user), 1000); // Hello from Rahul
</code></pre>
<h3>Summary — four ways <code>this</code> is determined</h3>
<pre><code class="language-plaintext">1. Called as a method     obj.method()       → this = obj
2. Called as a function   fn()               → this = global / undefined
3. Called with call/apply fn.call(obj)       → this = obj (you choose)
4. Called with bind       fn.bind(obj)()     → this = obj (permanently fixed)
</code></pre>
<p>And the special case:</p>
<pre><code class="language-plaintext">5. Arrow function         () =&gt; { this }     → this = inherited from lexical scope
</code></pre>
<hr />
<h2>Diagrams</h2>
<h3>Caller → Function Relationship</h3>
<pre><code class="language-plaintext">┌─────────────────────────────────────────────────────────────┐
│           CALLER → FUNCTION RELATIONSHIP                    │
│                                                             │
│  const user = {                                             │
│    name: "Priya",                                           │
│    greet: function() {                                      │
│      console.log(this.name);                                │
│    }                                                        │
│  };                                                         │
│                                                             │
│  ┌───────────────┐   calls    ┌────────────────┐            │
│  │  user         │ ─────────→ │  greet()       │            │
│  │  ─────────    │            │  ────────────  │            │
│  │  name: "Priya"│            │  this = user   │            │
│  │  greet: fn    │            │  this.name     │            │
│  └───────────────┘            │  = "Priya" ✓  │            │
│                               └────────────────┘            │
│                                                             │
│  ─────────────────────────────────────────────────────      │
│                                                             │
│  Same function, different caller:                           │
│                                                             │
│  ┌─────────────┐              ┌────────────────┐            │
│  │  person1    │ ─────────→  │  introduce()   │            │
│  │  name:Priya │  calls       │  this = person1│            │
│  └─────────────┘              │  → "Priya"     │            │
│                               └────────────────┘            │
│                                                             │
│  ┌─────────────┐              ┌────────────────┐            │
│  │  person2    │ ─────────→  │  introduce()   │            │
│  │  name:Rahul │  calls       │  this = person2│            │
│  └─────────────┘              │  → "Rahul"     │            │
│                               └────────────────┘            │
│                                                             │
│  ✦ Same function body — different this — different result   │
│  ✦ this is set at CALL TIME, not at WRITE TIME              │
└─────────────────────────────────────────────────────────────┘
</code></pre>
<h3>Different Contexts of <code>this</code></h3>
<pre><code class="language-plaintext">┌─────────────────────────────────────────────────────────────┐
│              DIFFERENT CONTEXTS OF `this`                   │
│                                                             │
│  CONTEXT              HOW CALLED          this VALUE        │
│  ─────────────────── ─────────────────── ──────────────     │
│                                                             │
│  Global scope         (top-level code)    window / global   │
│                                                             │
│  Object method        obj.method()        obj               │
│                                                             │
│  Plain function       fn()                window (or        │
│  (non-strict)                             undefined strict) │
│                                                             │
│  Arrow function       () =&gt; {}            inherited from    │
│                                           enclosing scope   │
│                                                             │
│  call / apply         fn.call(obj)        obj (you set it)  │
│                                                             │
│  bind                 fn.bind(obj)()      obj (locked in)   │
│                                                             │
│  ─────────────────────────────────────────────────────      │
│                                                             │
│  The lost `this` problem:                                   │
│                                                             │
│  const obj = {                                              │
│    name: "Priya",                                           │
│    start: function() {          ← this = obj here ✓        │
│      setTimeout(function() {                                │
│        console.log(this.name);  ← this = window ✗          │
│      }, 1000);     ↑                                        │
│    }          plain function callback — no caller object    │
│  };                                                         │
│                                                             │
│  Fix: use arrow function inside the method                  │
│  setTimeout(() =&gt; {             ← this inherited = obj ✓   │
│    console.log(this.name);      ← "Priya" ✓                │
│  }, 1000);                                                  │
│                                                             │
│  ✦ Arrow functions never have their own this                │
│  ✦ They borrow this from where they were written            │
└─────────────────────────────────────────────────────────────┘
</code></pre>
<hr />
<h2>Quick Reference</h2>
<pre><code class="language-javascript">// ─── this in global context ───────────────────────────────
console.log(this); // window (browser) / global (Node.js)

// ─── this in an object method ─────────────────────────────
const user = {
  name: "Priya",
  greet() {
    console.log(this.name); // "Priya" — this = user
  }
};
user.greet();

// ─── this in a plain function ─────────────────────────────
function show() {
  console.log(this); // window (non-strict) / undefined (strict)
}
show();

// ─── Arrow function inherits this ─────────────────────────
const obj = {
  name: "Priya",
  start() {
    setTimeout(() =&gt; {
      console.log(this.name); // "Priya" — arrow inherits from start()
    }, 1000);
  }
};

// ─── call() — invoke with specific this ───────────────────
function greet() { console.log(this.name); }
const person = { name: "Priya" };
greet.call(person);    // "Priya"

// ─── apply() — like call but args as array ────────────────
greet.apply(person);   // "Priya"

// ─── bind() — lock this permanently ──────────────────────
const boundGreet = greet.bind(person);
boundGreet();          // "Priya" — always

// ─── Summary ──────────────────────────────────────────────
// obj.method()     → this = obj
// fn()             → this = global / undefined
// fn.call(obj)     → this = obj
// fn.bind(obj)()   → this = obj
// () =&gt; {}         → this = inherited
</code></pre>
<hr />
<h2>Wrapping Up</h2>
<p><code>this</code> stops being confusing the moment you anchor it to one question: <strong>"Who is calling this function?"</strong></p>
<p>Here is everything you learned:</p>
<ul>
<li><p><code>this</code> is a dynamic keyword — its value is set at the time of the function call, not when the function is written</p>
</li>
<li><p>In <strong>global context</strong>, <code>this</code> is the <code>window</code> object (browser) or <code>global</code> (Node.js)</p>
</li>
<li><p>In <strong>object methods</strong>, <code>this</code> is the object that owns and calls the method</p>
</li>
<li><p>In <strong>plain functions</strong>, <code>this</code> is the global object (or <code>undefined</code> in strict mode)</p>
</li>
<li><p><strong>Arrow functions</strong> never have their own <code>this</code> — they inherit it from the surrounding scope, making them ideal for callbacks inside methods</p>
</li>
<li><p>You can manually control <code>this</code> using <code>call()</code>, <code>apply()</code>, and <code>bind()</code></p>
</li>
<li><p>The most common bug: passing an object method as a callback and losing <code>this</code> — fix it with <code>bind()</code> or an arrow function</p>
</li>
</ul>
<p>Once you internalise <em>"this is the caller"</em>, every case in this guide will make sense on first read — and debugging <code>this</code>-related bugs becomes straightforward.</p>
<p>Happy coding! 🚀</p>
<hr />
<p><em>Next step: Practice by writing objects with multiple methods, calling them in different ways, and logging</em> <code>this</code> <em>each time. Five minutes of experimentation teaches more than an hour of reading.</em></p>
]]></content:encoded></item></channel></rss>