this

A special keyword that refers to whatever object is currently 'in charge' of the running code.

What is it?

Sometimes code inside a function needs to refer to "the object I belong to" without naming that object directly — so the same code can work for many different objects. JavaScript provides a special keyword, this, that refers to that object.

The tricky part: this isn't fixed to where a function is written — it depends on how the function is called. The same function can have a different this each time you call it differently.

Explain like I'm 10

Think of "this" like the word "I" in a sentence. The word itself doesn't change, but who "I" refers to depends entirely on who's speaking at the time.

Examples

`this` depends on how a function is called

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

user.greet(); // "Hi, I'm Amara" — this = user, because user.greet() called it

const greetFn = user.greet;
greetFn(); // "Hi, I'm undefined" — this is no longer "user" here

Calling user.greet() sets this to user. But once the function is detached from user and called on its own, this no longer points to user.

Arrow functions and `this`

const user = {
  name: "Amara",
  greet: () => {
    console.log("Hi, I'm " + this.name); // ❌ arrow functions don't have their own "this"
  },
};

Arrow functions intentionally don't have their own this — they use this from the surrounding code where they were written, which is usually not what you want for object methods.

How it works

When a regular function is called, JavaScript looks at how it was called to decide what this should be: calling it as obj.method() sets this to obj; calling it plain, like fn(), sets this to undefined (in strict mode) or the global object; and .call()/.apply()/.bind() let you set this explicitly. Arrow functions skip this process entirely and just borrow this from their enclosing scope.

Why does it exist?

this lets the same method definition work correctly for many different objects — one greet method can be shared by every user object, each correctly referring to itself, instead of needing a separate hardcoded copy per object.

When to use it

You need to reason about this any time you write a method on an object, use a class, or pass a function around as a callback — knowing what this will be tells you whether that code will actually work when it's called.

When not to use it

In plain or arrow functions that don't depend on an object's own data, you often don't need this at all — a regular parameter is clearer. And inside object methods that get used as callbacks, prefer an arrow function or .bind() over relying on the caller to preserve this correctly.

Common mistakes

  • Passing an object method as a callback (e.g. to setTimeout) and losing its intended this.

  • Using a regular function for an object method that's called as a plain callback, instead of binding it or using an arrow function appropriately.

  • Assuming this refers to where a function is defined rather than how it's called.

Practice exercises

  1. Easy:

    Create an object with a method that logs this.name, and call it normally to confirm it works.

  2. Medium:

    Detach that method into its own variable, call it directly, and explain why this breaks.

  3. Hard:

    Fix the broken example using .bind(), and explain what .bind() actually does.

Interview questions

What determines the value of `this` inside a regular function?

How the function is actually called at the call site — not where it was defined. Calling it as obj.method() sets this to obj; calling it standalone as fn() gives a different this entirely; new fn() and .call/.apply/.bind each set it differently again.

What does `this` become when a regular function is called completely standalone, like `fn()`, with no object in front of it?

In strict mode, this is undefined. In non-strict ("sloppy") mode, it falls back to the global object (window in a browser) instead — a long-standing default that strict mode was introduced partly to avoid, since accidentally leaking global-object access is rarely what anyone wants.

What is `this` set to inside a method called as `obj.method()`?

obj itself — whatever object appears directly to the left of the dot at the moment of the call is what this is bound to for that invocation.

Where does an arrow function get its `this` from?

It doesn't have its own this binding at all — it looks outward to whatever this is in the surrounding (lexical) scope where the arrow function was written, and that value never changes no matter how the arrow function itself is later called.

If you copy a method off an object into a plain variable and call it from there, what happens to `this`?

The connection to the original object is lost — calling the copied function standalone triggers the same rule as any other standalone call (undefined in strict mode, or the global object otherwise), not the object it came from.

What does `fn.call(thisValue, arg1, arg2)` do?

It immediately invokes fn, explicitly setting this to thisValue for that one call, passing arg1, arg2, ... as individual arguments.

How does `.apply()` differ from `.call()`?

They do the exact same thing — invoke immediately with an explicit this — but .apply() takes its arguments bundled as a single array (or array-like), while .call() takes them as a comma-separated list.

What does `.bind()` do, and when is the `this` you pass to it actually locked in — immediately, or only once the bound function is finally called?

It returns a brand-new function with this permanently fixed to whatever you passed, and that binding happens immediately, at the moment .bind() is called — not deferred until the new function is eventually invoked.

Once a function has been bound with `.bind()`, can a later `.call()` or `.apply()` on the resulting function override its `this`?

No — a bound function's this is permanently locked in; any this you try to pass via a later .call()/.apply() on it is simply ignored.

What happens to a bound function's `this` if it's called with `new` instead of as a plain function?

new wins — calling a bound function with new ignores the bound this entirely and instead creates a fresh object for this, the same as calling the original unbound function with new would. The bound arguments (if any were pre-supplied) are still used, but not the bound this.

What's the actual priority order JavaScript uses when several of these rules could apply at once — `new`, explicit binding (`call`/`apply`/`bind`), an object method call, and the plain default?

From highest to lowest priority: calling with new always wins; then an explicit this set via call/apply/bind; then an implicit this from a method call (obj.method()); and only if none of those apply does it fall back to the default (undefined in strict mode, or the global object otherwise).

If you pass an object's method directly to `setTimeout(obj.method, 1000)` instead of wrapping it, what is `this` when it eventually runs?

Not obj — setTimeout calls the function standalone with no object in front of it, so this falls back to the default (undefined in strict mode), the same problem as detaching any method into a plain variable and calling it later.

What are two idiomatic ways to fix a callback that's losing its intended `this`?

Either wrap the call in an arrow function at the call site (setTimeout(() => obj.method(), 1000), so obj.method() is still called as a method), or pre-bind it once with .bind() (setTimeout(obj.method.bind(obj), 1000)), locking in this regardless of how it's later invoked.

If a plain (non-arrow) function is defined inside an object's method and called from inside that method, does it inherit the method's `this`?

No — a plain nested function called on its own gets its own default this, completely independent of the outer method's this, which is a classic and easy-to-miss gotcha; an arrow function defined in the same spot would correctly inherit the outer method's this instead.

Inside a DOM event handler written as a regular function, what does `this` refer to?

The element the listener was attached to — the browser calls the handler as if it were a method on that element, effectively element.handler(event), which is why this inside it points to the element.

If that same event handler is written as an arrow function instead, does `this` still refer to the element?

No — an arrow function ignores the element-based this the browser would otherwise supply, and instead uses whatever this was in scope where the arrow function was originally written, which is usually not the element at all.

If a class method is passed around as a callback (e.g. `<button onClick={instance.method}>`) without binding it first, what typically goes wrong?

The method loses its connection to instance the same way any detached method does — when it's later called as a plain callback, this inside it is no longer instance, so any code inside relying on this.someProperty breaks.

How does the "class field arrow function" pattern (`method = () => { ... }` instead of `method() { ... }`) fix the lost-`this` callback problem?

Because it's an arrow function, it doesn't get its own this — it captures this lexically from where it's defined, which is inside the constructor's scope, where this is the instance being built. Since it's assigned per-instance as an instance property (not shared on the prototype), each instance gets its own already-bound version, safe to pass around as a callback without ever losing track of this.

What is `this` set to inside a constructor function invoked with `new`?

The brand-new, freshly created object that new is in the process of building — assignments like this.name = name inside the constructor attach properties directly onto that new instance.

What does `this` refer to inside a `static` method of a class?

The class (constructor function) itself, not any particular instance — since static methods are called directly on the class, like MyClass.staticMethod(), not on an instance.

What does `this` refer to inside a getter or setter defined in a class?

The specific instance the getter/setter is being accessed through — exactly the same as this inside a regular instance method, letting the accessor read or modify that instance's own data.

Does `this` behave any differently inside a generator function's body compared to a regular method?

No — a generator method still follows the exact same call-site rules for this as any other method; being a generator only changes how it produces values (via yield), not how this is determined.

What is `this` at the very top level of an ES module, outside any function?

undefined — unlike a classic non-module script, where top-level this refers to the global object, an ES module's top-level this is deliberately undefined, since modules are implicitly in strict mode and don't have an ambient global this.

Does writing `"use strict"` change what `this` is inside a method call like `obj.method()`?

No — it only changes the default, standalone-call case. this inside obj.method() is obj either way; strict mode's effect on this specifically matters for a plain fn() call, changing the fallback from the global object to undefined.

Why did some older codebases write `const self = this;` at the top of a method, before arrow functions were common?

So that a nested plain function (which would otherwise get its own, different this) could reference the outer method's this indirectly through the closed-over self variable instead — a manual workaround for the exact problem arrow functions later solved automatically by inheriting this lexically.

Predict the output: `function show() { console.log(this.id); } const a = { id: 1, show }; const b = { id: 2 }; show.call(b);`

2 — .call(b) explicitly sets this to b for that one invocation, completely overriding whatever this would otherwise have been (even though show also happens to exist as a.show, that's irrelevant here since it's being called through .call, not through a).

Predict the output: `function sum(a, b) { return this.multiplier * (a + b); } console.log(sum.apply({ multiplier: 10 }, [2, 3]));`

50 — .apply() sets this to { multiplier: 10 } and unpacks the array [2, 3] as the individual arguments a and b, giving 10 * (2 + 3).

Predict the output: `function greet(greeting) { console.log(greeting + ", " + this.name); } const hi = greet.bind({ name: "Amara" }, "Hi"); hi();`

"Hi, Amara" — .bind() locks in both this ({ name: "Amara" }) and the first argument ("Hi") at bind time; calling hi() later needs no further arguments and always uses that fixed this.

What is `this` inside an IIFE (immediately invoked function expression) written as a plain function, called with no object?

The same as any other standalone call — undefined in strict mode, or the global object otherwise — since an IIFE is still just a regular function invocation, with nothing to its left setting an implicit this.

If an arrow function is defined directly inside a regular method, does it correctly inherit that method's `this`?

Yes — this is one of the main reasons arrow functions exist: since they don't have their own this, an arrow function written inside a method automatically picks up the method's own this, which is usually exactly what you want for a nested helper or callback.

Can you reassign `this` inside a function body the way you would a normal variable, like `this = someObject;`?

No — this isn't a regular variable at all; it's determined entirely by how the function was called, and attempting to assign directly to it is a syntax error.

Does calling `.call()` or `.apply()` on an arrow function actually change what `this` resolves to inside it?

No — arrow functions permanently ignore any this argument passed via .call, .apply, or .bind; those methods still pass through any other arguments normally, but the this portion has no effect on an arrow function's body.

If you pass an object's method directly as the callback to `array.map(obj.method)`, what typically goes wrong with `this` inside it?

The same detached-method problem as anywhere else — map calls the callback as a plain function, not as obj.method(), so this inside it is no longer obj. Fixing it means either using an arrow function wrapper (array.map(x => obj.method(x))), pre-binding (array.map(obj.method.bind(obj))), or passing obj as map's optional thisArg second argument.

Debugging: an event listener written as `element.addEventListener("click", instance.handleClick)` logs `this.state` as `undefined` instead of the expected instance data. What's the fix?

instance.handleClick is detached from instance the moment it's passed as a bare reference, so when the browser calls it, this is the element (or undefined in a class method, since class bodies are strict mode), not instance. Binding it explicitly — instance.handleClick.bind(instance), or defining it as a class field arrow function in the first place — keeps this pointing at instance regardless of how the browser invokes it.