How does the this keyword work in JavaScript?

Intermediate12 min interview
Skills tested:
Four rules for this binding: default, implicit, explicit, newLexical this in arrow functionsthis in strict mode vs sloppy modeLosing this context when extracting a method as a callbacknew binding and constructor function behavior

Advertisement

🧩 Scenario

In a real codebase, this binding bugs are most common when passing class methods as callbacks to event listeners, timers, or array methods. The method loses its object context when called by the invoker rather than by the object. Understanding the four binding rules allows you to predict this in any situation and choose the right fix: bind, arrow function wrapper, or class field.

Architecture Walkthrough

The Four Binding Rules

JavaScript determines this by four rules applied in order of precedence from lowest to highest. The default binding applies when a function is called with no receiver: in non-strict mode, this is the global object (window in browsers); in strict mode, this is undefined. Implicit binding applies when a function is called as a method of an object: obj.method() sets this to obj.

Explicit binding applies when call, apply, or bind is used to specify this directly. new binding applies when a function is called with the new keyword: a new empty object is created, this inside the constructor refers to it, and the new object is returned implicitly unless the constructor explicitly returns a different object.

Losing this When Extracting Methods

The most common this bug occurs when a method is extracted from an object and called without the object as the receiver. The invocation context determines this, not the definition context. Once the method reference is stored in a standalone variable or passed as a callback, the link to the original object is broken.

Three fixes are available: call bind(this) to create a permanently bound function, wrap the call in an arrow function that closes over the correct this, or use a class field arrow function which captures this at class instantiation time rather than at call time. Each approach has different readability and performance implications.

Arrow Functions and Lexical this

Arrow functions do not have their own this binding. They inherit this from the lexical scope where they are defined, not from where they are called. This makes them predictable for callbacks inside class methods or factory functions: whatever this was in the surrounding scope when the arrow function was defined is what this will always be inside it.

The consequence is that arrow functions cannot be used as constructors (new arrowFn() throws), and call, apply, or bind has no effect on this inside an arrow function. The first argument to these methods is silently ignored.


Key Code Explained

// Default binding
function show() {
  console.log(this);
}
show(); // window (non-strict) or undefined (strict)

// Implicit binding
const user = {
  name: 'Ghazi',
  greet() { console.log(this.name); },
};
user.greet(); // 'Ghazi' — this is user

// Losing this: extraction breaks implicit binding
const greet = user.greet;
greet(); // undefined (strict mode) — this is no longer user

// Fix 1: bind
const boundGreet = user.greet.bind(user);
boundGreet(); // 'Ghazi'

// Fix 2: arrow wrapper
setTimeout(() => user.greet(), 1000); // 'Ghazi' — closure over user

// Explicit binding
function introduce(role) {
  console.log(`${this.name} is a ${role}`);
}
introduce.call(user, 'developer'); // 'Ghazi is a developer'

// new binding
function Person(name) {
  this.name = name; // this is the new object
}
const p = new Person('Ghazi');
console.log(p.name); // 'Ghazi'

// Arrow function: lexical this, cannot be rebound
const obj = {
  name: 'Obj',
  regular() { console.log(this.name); },
  arrow: () => { console.log(this.name); }, // this is outer scope at definition
};
obj.regular(); // 'Obj'
obj.arrow();   // undefined — this is lexical, not obj

The extraction example is the most important: const greet = user.greet followed by greet() loses the implicit binding to user. The function runs in default mode, so this becomes undefined in strict mode. The three fixes demonstrate the range of solutions available depending on whether you need a one-time binding, a reusable wrapper, or a class-level fix.


Tradeoffs

Binding approachWhen this is setRebindable
Default (standalone call)At call time, to global or undefinedNot applicable
Implicit (method call)At call time, to the calling objectYes, by changing the caller
Explicit (call/apply/bind)Forced at call time or permanentlyYes, except on arrow functions
newAt construction time, to new objectNo
Arrow function (lexical)At definition time, from surrounding scopeNo, call/apply/bind have no effect

What Interviewers Actually Check

  • Whether you can name and rank all four binding rules correctly
  • Whether you can predict this in a standalone call, a method call, a new call, and an arrow function
  • Whether you understand why extracting a method and calling it as a function loses this
  • Whether you can describe at least two ways to fix a lost this context
  • Whether you know that arrow functions capture this lexically and cannot be rebound

Follow-Up Questions

  1. What does this refer to inside a class static method?
  2. If a constructor function explicitly returns an object, what does new return?
  3. How do class field arrow functions differ from binding in the constructor in terms of memory usage?
  4. What is the value of this inside a method called in an Array.prototype.forEach callback written as a regular function?
  5. A teammate says "just use arrow functions everywhere to avoid this bugs." Where does that advice break down?

Common Candidate Mistakes

  • Assuming this inside a method still refers to the object after the method is extracted and called as a standalone function
  • Thinking arrow functions can be rebound with call or bind when they cannot
  • Not knowing that a regular function called without a receiver uses undefined for this in strict mode, not the global object
  • Confusing this inside a nested regular function inside an object method, which defaults to undefined in strict mode
  • Saying "arrow functions always work for this" without knowing they break when used as object methods

Interview Readiness Checklist

Before you leave this question, make sure you can answer:

  • Can you name all four this binding rules and rank them by precedence?
  • Can you predict what this is in a standalone function call, a method call, a new call, and an arrow function?
  • Can you explain why extracting a method and calling it as a standalone function loses its original this?
  • Can you fix a lost this context using bind, an arrow function wrapper, or a stored reference?
  • Can you explain what new does to this inside a constructor function?

Summary

The value of this in JavaScript is determined by how a function is invoked, not where it is defined. Four rules apply in order of precedence: default binding (standalone call, this is global or undefined), implicit binding (method call, this is the calling object), explicit binding (call/apply/bind, this is specified), and new binding (constructor call, this is the new object).

Arrow functions break this pattern entirely. They do not have their own this. They capture this lexically from their surrounding scope at the time they are defined, and no binding mechanism can change it.

The most common bug is losing implicit binding when a method is extracted and called without its object. The fix is either bind for a permanent binding, an arrow wrapper for a one-time call, or class field syntax for a class-level permanent solution. Knowing these four rules and their precedence covers the vast majority of this questions in any JavaScript interview.

Related Videos
Watch these videos to learn more about this topic
Frequently Asked Questions

Does "this" refer to the function itself?

No. It refers to the object that invoked the function, or is determined by call-time context depending on how the function is called.

Advertisement


Stay Updated

Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.

Advertisement