DEV Community

Hamza Khan
Hamza Khan

Posted on

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

"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!

Top comments (0)