← All concepts
Behind the Scenes

The this Keyword

this is not fixed to a function; it is decided fresh by how that function gets called.

Definition

Unlike a regular variable, `this` is not resolved through the scope chain. Its value is determined by the call site, meaning the same function body can produce a different `this` depending on how it is invoked. Called as a method (`obj.greet()`), `this` is the object before the dot. Called standalone (`greet()`), `this` is `undefined` in strict mode (or the global object in non-strict code). Called with `.call()`, `.apply()`, or `.bind()`, `this` is whatever object you explicitly pass in, regardless of how the function is normally attached. Arrow functions break this pattern on purpose: they have no `this` of their own and instead capture `this` lexically from the scope where they were defined, the same way a closure captures a variable. That makes arrow functions useful inside methods or callbacks where you want `this` to stay pointed at the surrounding object instead of being reset by the caller.

Examples

const person = {
  name: "Ada",
  greet() { return this.name; },
};
person.greet(); // "Ada"

const detached = person.greet;
detached(); // undefined (this is not person anymore)

As a method call, this is the object before the dot. Once the function is pulled off the object and called standalone, this loses that binding.

function greet() { return this.name; }
const bound = greet.bind({ name: "Bo" });
bound(); // "Bo"

const arrowGreet = () => this;
// this inside the arrow is whatever this was outside it, fixed forever

bind permanently locks this to the object you pass in. An arrow function ignores call-site rules entirely and keeps the this of its enclosing scope.

Common mistakes

  • Pulling a method off an object and calling it standalone, then being surprised `this` is no longer that object.
  • Using a regular function for a callback where you wanted `this` to stay pointed at the enclosing object, instead of an arrow function.
  • Assuming `.bind()` only affects the next call; it permanently locks `this` for every future call of that bound function.

Key takeaways

  • `this` is decided by the call site, not by where the function was defined.
  • Method calls set `this` to the object before the dot; standalone calls do not.
  • `.call()`, `.apply()`, and `.bind()` let you set `this` explicitly.
  • Arrow functions have no `this` of their own; they capture it lexically from the enclosing scope.
Check your understanding

A method is detached from its object and called as a plain function: `const fn = obj.greet; fn();`. What is `this` inside fn (in strict mode)?

Where you see this

  • Choosing arrow functions for callbacks (event handlers, array methods) so this still points at the class or object that set them up.
  • Using .bind() to pass an object method as a callback without losing its this.
  • Debugging a 'cannot read property of undefined' error caused by detaching a method from its object.
  • Understanding why React class components historically bound handlers in the constructor.

Practice this

Further reading

Previous
The Scope Chain
Next
Execution Context and the Call Stack