JavaScript this

The Most Surprising Keyword

JavaScript this

`this` refers to the "context" of a function call. The rules depend on how the function is called — not where it was defined.

6 min read Level 4/5 #this#context#methods
What you'll learn
  • Identify what `this` refers to in different call styles
  • Know that arrow functions don't have their own `this`
  • Recognize the "lost this" callback bug

this is a special keyword inside a function. Its value depends on how the function is called, not where it’s defined. There are four rules.

Rule 1: Method Call

When you call a function as a method (obj.method()), this is the object before the dot.

this in a method script.js
const user = {
  name: "Ada",
  greet() {
    console.log(`Hi, I'm ${this.name}`);
  },
};

user.greet();  // "Hi, I'm Ada"
▶ Preview: console

Rule 2: Plain Function Call

When you call a function on its own (not as a method), this is undefined in strict mode (and the global object in sloppy mode). Modules are always strict.

Plain call — this is undefined script.js
function greet() {
  console.log(this);
}

greet();  // undefined (in strict mode / a module)
▶ Preview: console

Rule 3: Arrow Functions Inherit

Arrow functions don’t get their own this. They use the this of the enclosing scope.

Arrow inherits this script.js
const user = {
  name: "Ada",
  greet() {
    const innerArrow = () => {
      console.log(`Hi, I'm ${this.name}`);  // this from greet
    };
    innerArrow();
  },
};

user.greet();  // "Hi, I'm Ada"
▶ Preview: console

Rule 4: new-bound

When you call a function with new, this is the brand-new object being constructed.

this in a constructor script.js
function User(name) {
  this.name = name;  // this = the new object
}

const ada = new User("Ada");
console.log(ada);  // User { name: 'Ada' }
▶ Preview: console

This is mostly used through class syntax, which we’ll cover next chapter.

The “Lost this” Bug

Here’s the most common this bug. Take a method off an object and call it standalone — this is no longer the object.

Lost this script.js
const user = {
  name: "Ada",
  greet() {
    console.log(this?.name);
  },
};

user.greet();      // "Ada"          ✅ method call

const fn = user.greet;
fn();              // undefined      😱 plain call, this is undefined
▶ Preview: console

user.greet (without calling) gives you the function itself, no object attached. When you later call it, you lose the connection to user.

This bites with callbacks too:

Lost in a callback script.js
const user = {
  name: "Ada",
  greet() {
    console.log(this?.name);
  },
};

// setTimeout calls the function as a plain function — this is lost.
setTimeout(user.greet, 10);  // logs undefined

// Fix 1: wrap in an arrow that closes over user.
setTimeout(() => user.greet(), 10);

// Fix 2: bind explicitly (next lesson).
setTimeout(user.greet.bind(user), 10);
▶ Preview: console

Arrow Methods Misbehave

Because arrows don’t get their own this, using them AS methods usually doesn’t work the way beginners expect.

Don't use arrows as object methods script.js
const user = {
  name: "Ada",
  greet: () => {
    console.log(this?.name); // this here is NOT user
  },
};

user.greet();  // undefined  — arrow doesn't bind to user
▶ Preview: console

For object methods, use regular methods (greet() { … }). For callbacks INSIDE methods, arrow functions are great.

Cheatsheet

How you call itWhat this is
obj.fn()obj
fn() (plain call)undefined (in strict)
new Fn()new object being constructed
Arrow () => … anywhereinherited from enclosing scope
Inside setTimeout(fn, ...)undefinedfn is called plainly

Up Next

When the default this isn’t what you want, you can set it explicitly with call, apply, or bind.

JavaScript call, apply, bind →