DevAcademy
LearnJavaScriptThe "this" Keyword
IntermediateJavaScript

The "this" Keyword

Learn how JavaScript decides what "this" refers to based on how a function is called, why arrow functions behave differently, and how to fix a "this" that gets lost in a callback.

Reading Time

18 min

Lesson

Lesson 37 of 48

this Depends on How a Function is Called

The single most important rule about this is that its value is determined by how a function is called, not by where the function is defined. The same function can produce a completely different this depending on whether you call it as a standalone function, as a method on an object, with .call()/.apply(), or with the new keyword. This trips up a lot of developers coming from languages where a method's receiver is fixed at definition time — in JavaScript, this is decided fresh at call time.

this in the Global Context

When this is used outside of any function, it refers to the global object — window in a browser, or global in Node. Inside a regular function called on its own (not as a method), this is undefined in strict mode (which includes the top level of ES modules and class bodies), or falls back to the global object in non-strict, 'sloppy' mode.

this Outside of Any Object

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

this Inside an Object Method

When a function is called as a method — that is, accessed off an object right before being invoked, like obj.method() — this inside that function refers to the object it was called on. This is the most common and intuitive use of this: it lets a method read and update the data that belongs to its own object.

this Inside a Method Call

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

Regular Functions vs. Arrow Functions

Regular functions get their own this, freshly determined every time they're called. Arrow functions do not have their own this at all — instead, they capture this lexically from the scope in which they were defined, exactly the way closures capture variables. That means an arrow function's this is whatever this was in the surrounding code where the arrow function was written, and it never changes no matter how the arrow function is later called.

Arrow Functions Inherit this Lexically

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

Losing this in a Callback

A very common bug happens when a method is passed around as a plain reference — for example, to setTimeout(), an event listener, or as a callback argument. Once a method is detached from the object it was defined on, calling it no longer counts as obj.method(), so this is no longer bound to obj. The function is called on its own, and this reverts to undefined (in strict mode) or the global object.

this Getting Lost

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

Fixing it with bind(), call(), and apply()

JavaScript gives you three built-in tools to explicitly control what this refers to. .call(thisArg, ...args) and .apply(thisArg, argsArray) both invoke a function immediately with this set to whatever you pass as the first argument — they differ only in how they accept the remaining arguments. .bind(thisArg) is different: it doesn't call the function, it returns a brand-new function with this permanently locked to thisArg, which is exactly what you want when passing a method somewhere else to be called later.

Fixing a Lost this

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

call() vs. apply() vs. bind()

MethodInvokes Immediately?How Extra Args Are PassedReturns
call()YesListed one by oneThe function’s return value
apply()YesAs a single arrayThe function’s return value
bind()NoListed one by one (optional, preset)A new function with this locked

this Inside a Class

Inside a class, this behaves like it does in a regular object method: within an instance method, this refers to the specific instance the method was called on. But the same danger applies — if you pass a class method as a callback without binding it, this will be lost. This is why you often see this.method = this.method.bind(this) inside class constructors, or class fields defined as arrow functions, which lexically capture the instance this and never lose it.

this Inside a Class, and How to Protect It

Try it yourself — edit and run

Console Output

Click “Run” to see the console output here.

Quick Rules for Figuring Out this

  • Called as obj.method() → this is obj
  • Called as a plain function() → this is undefined (strict mode) or the global object
  • Called with new Constructor() → this is the newly created instance
  • Called with .call()/.apply() → this is whatever you passed in
  • Defined as an arrow function → this is inherited from the enclosing scope, always

Watch Out When Passing Methods Around

Any time you extract a method off an object and hand it somewhere else — a callback, an event listener, a setTimeout() — you are at risk of losing this. Always ask: 'is this function still being called as obj.method(), or has it been detached?' If it's detached, either bind it first, wrap it in an arrow function at the call site, or convert it to an arrow function class field.

When in Doubt, console.log(this)

If you're ever unsure what this will be inside a particular function, the fastest way to find out is to log it right there and run the code — this depends entirely on the call site, so reasoning about the source code alone can be misleading, especially with callbacks.

Interview Questions

Quick Quiz

1. What primarily determines the value of this inside a function?

2. How does an arrow function determine its this value?

3. What happens when you pass user.greet (a method) to setTimeout() without binding it?

4. Which method returns a new function with this permanently set, rather than invoking the function immediately?

5. Inside a class constructor, why might you write this.method = this.method.bind(this)?

6. What does this code log?

const obj = {
  name: "Asha",
  regular: function () {
    return this.name;
  },
  arrow: () => {
    return this.name;
  },
};

console.log(obj.regular());
console.log(obj.arrow());

7. What does this code log?

function Person(name) {
  this.name = name;
  setTimeout(function () {
    console.log(this.name);
  }, 0);
}

new Person("Rahul");