The 'this' Keyword

⭐ Interview Importance: HIGH
⏱️ Revision Time: 5 min

TL;DR

In traditional JavaScript functions, this is NOT determined by where a function is written. It is determined by HOW the function is called at runtime. It represents the object that is executing the current function.

Mental Model

How It Works

There are 4 main rules for this in traditional functions:

  1. Implicit Binding (Object Method): If a function is called with a dot (obj.method()), this is the object to the left of the dot.
  2. Explicit Binding: You manually force this using .call(), .apply(), or .bind().
  3. New Binding: If a function is called with the new keyword, this points to a brand new empty object being constructed.
  4. Default Binding: If a function is called completely bare (myFunc()), this defaults to the global object (window in browsers). If Strict Mode is on, it defaults to undefined.

Note: Arrow functions completely ignore all 4 rules and just use Lexical Scoping.

Example

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

// 1. Implicit Binding
user.greet(); // "Hi, I'm Alice" (Object to the left of the dot is 'user')

// 2. The Trap! Losing 'this'
const looseGreet = user.greet;
looseGreet(); // "Hi, I'm undefined" (Called bare! Default binding applies)

// 3. Explicit Binding to fix it
looseGreet.call(user); // "Hi, I'm Alice"

// 4. New Binding
function Person(name) {
  this.name = name; // 'this' is a new {}
}
const p = new Person("Bob");

Common Output Question

const length = 4;
function callback() {
  console.log(this.length);
}

const obj = {
  length: 5,
  method(fn) {
    fn();
  }
};

obj.method(callback);

Q: What does this output and why?
A: 4 (in a browser, without strict mode).
Even though callback is passed into obj, look at how it is invoked inside method: fn();. It is called bare! There is no dot to the left of it. Therefore, Default Binding applies. this becomes the global window object. window.length happens to be 4 because var length = 4 at the top level creates a property on the window. (If using let, it would be 0 or undefined depending on the environment).

Senior Interview Question

Q: In an event listener, what does this point to?

A: By default, in a standard DOM event listener (button.addEventListener('click', function() { ... })), the browser automatically binds this to the DOM element that fired the event (the button).
However, if you pass an Arrow Function as the callback (button.addEventListener('click', () => { ... })), it will completely ignore the browser’s attempt to bind this to the button, and this will point to the surrounding lexical scope (often the window or the class that created the listener).