🔍 Everything You Need to Know About `this` in JavaScript (2025 Edition)
Hamza Khan

Hamza Khan @hamzakhan

About: Passionate software engineer specializing in web development, and CRM Development. Constantly learning and exploring new technologies to stay ahead. Let's code together! 🚀

Location:
Lahore, Pakistan
Joined:
May 2, 2024

🔍 Everything You Need to Know About `this` in JavaScript (2025 Edition)

Publish Date: Jun 3
2 0

"this is not what you think it is... until it is." — Every JS Developer Ever

JavaScript’s this keyword is one of the most misunderstood and debated features of the language. It's dynamic, context-sensitive, and changes depending on how a function is called—not where it's defined.

In this article, we’ll break down this from fundamental to advanced use cases. Whether you're debugging a callback, building a class, or optimizing performance, understanding this can drastically improve how you write JavaScript.

🚀 What is this?

In JavaScript, this refers to the execution context of a function. It determines what object is "speaking" during that call.

But unlike many languages where this is statically bound, JavaScript’s this is dynamically scoped, which means it can vary based on how a function is invoked.

📌 Rule 1: Global Context

In the global scope, this refers to:

  • window in the browser
  • global in Node.js (non-strict mode)
console.log(this); // browser: Window, node: global
Enter fullscreen mode Exit fullscreen mode

However, in strict mode ('use strict'), this is undefined in the global scope.

'use strict';
console.log(this); // undefined
Enter fullscreen mode Exit fullscreen mode

📌 Rule 2: Object Method Context

When a function is called as a method of an object, this refers to that object.

const user = {
  name: "Alice",
  greet() {
    console.log(`Hello, I am ${this.name}`);
  },
};

user.greet(); // "Hello, I am Alice"
Enter fullscreen mode Exit fullscreen mode

📌 Rule 3: Standalone Function Context

When a function is called without an object, this refers to the global object in non-strict mode, and undefined in strict mode.

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

standalone(); // non-strict: global; strict: undefined
Enter fullscreen mode Exit fullscreen mode

📌 Rule 4: Constructor Functions and Classes

When using new, this refers to the newly created object.

function Person(name) {
  this.name = name;
}

const p = new Person("Bob");
console.log(p.name); // Bob
Enter fullscreen mode Exit fullscreen mode

In ES6 classes:

class Car {
  constructor(model) {
    this.model = model;
  }

  showModel() {
    console.log(this.model);
  }
}

const c = new Car("Tesla");
c.showModel(); // Tesla
Enter fullscreen mode Exit fullscreen mode

📌 Rule 5: Arrow Functions (Lexical this)

Arrow functions don’t have their own this. Instead, they lexically bind to the enclosing scope’s this.

const obj = {
  count: 0,
  increment: function () {
    const arrow = () => {
      this.count++;
    };
    arrow();
  },
};

obj.increment();
console.log(obj.count); // 1
Enter fullscreen mode Exit fullscreen mode

This is super helpful when dealing with methods inside callbacks.

📌 Rule 6: call, apply, and bind

These methods let you explicitly set the value of this.

function greet() {
  console.log(`Hello, ${this.name}`);
}

const user = { name: "Charlie" };

greet.call(user);  // Hello, Charlie
greet.apply(user); // Hello, Charlie

const bound = greet.bind(user);
bound(); // Hello, Charlie
Enter fullscreen mode Exit fullscreen mode

📌 Rule 7: Event Handlers

In browser event handlers, this refers to the DOM element that fired the event.

document.getElementById("btn").addEventListener("click", function () {
  console.log(this); // <button id="btn">...</button>
});
Enter fullscreen mode Exit fullscreen mode

But with arrow functions:

document.getElementById("btn").addEventListener("click", () => {
  console.log(this); // Lexical: likely `window` or enclosing scope
});
Enter fullscreen mode Exit fullscreen mode

Use regular functions when this should refer to the DOM element.

🧠 Common Gotchas

  1. Losing this in Callbacks:
   const obj = {
     name: "Jane",
     greet() {
       setTimeout(function () {
         console.log(this.name); // undefined
       }, 1000);
     }
   };
Enter fullscreen mode Exit fullscreen mode

Fix with arrow function:

   setTimeout(() => {
     console.log(this.name); // Jane
   }, 1000);
Enter fullscreen mode Exit fullscreen mode
  1. Binding in Loops: Don’t forget to bind this in iterative or recursive functions when needed.

🔍 Deep Dive: this in ES Modules

In ES modules (.mjs), this at the top level is undefined by design.

console.log(this); // undefined in strict mode modules
Enter fullscreen mode Exit fullscreen mode

✨ Summary Table

Invocation Type Value of this
Global (non-strict) window / global
Global (strict) undefined
Object method The object
Standalone function undefined (strict)
Constructor (new) New instance
Arrow function Lexical scope
Event listener (DOM) Event target
call, apply, bind Explicitly defined

💬 Final Thoughts

Understanding this is essential for mastering JavaScript in 2025. With the shift towards more declarative code, TypeScript, and functional patterns, this may seem like a relic—but it’s still heavily used across frameworks, libraries, and core JS behaviors.

If you're building libraries, working with classes, or handling complex callbacks—mastering this will set you apart.

🗨️ What are your biggest this-related bugs or insights? Drop them in the comments!

Comments 0 total

    Add comment