Engrain by ByteRush

JS.03.01 Junior· 10 minCore — asked often

The four rules of this: how JavaScript decides what this is

this is set by how a function is called, not where it is written. Learn the four binding rules, their order, and why passing a method as a callback loses this.

Comes up in: JavaScript, Recruiter screen

Learn#

Tara writes button.addEventListener("click", cart.checkout). Clicking throws “Cannot read properties of undefined (reading ‘items’)”. cart.checkout() works fine in the console. Same function — different this.

this is not decided where a function is written. It is decided by how it is called. Four rules:

  1. Method call: obj.fn() — this is the object before the dot, the receiver. This is implicit binding.
  1. Plain call: fn() — this is undefined in strict code (modules, classes), or the global object in sloppy scripts.
  1. Explicit: fn.call(x), fn.apply(x) or fn.bind(x) — this is x.
  1. new: new Fn() — this is a brand-new object.
function hello() { return "Hi, " + this.name; }
const user = { name: "Asha", hello };
console.log(user.hello());
const loose = user.hello;
try { loose(); } catch (e) { console.log(e.name + ": " + e.message); }
console.log(loose.call({ name: "Ravi" }));
function Person(name) { this.name = name; }
console.log(new Person("Mei").name);

Output (verified)

Hi, Asha
TypeError: Cannot read properties of undefined (reading 'name')
Hi, Ravi
Mei

Passing cart.checkout as a callback copies only the function, so it is later called plainly — rule 2. That is Tara’s bug. (Error text is from V8.)

Same function, four different thisStep 1 of 5

call

  • user.hello()

this

  • user

Console

  • Hi, Asha

user.hello() — there is an object before the dot, so this = user.

Read the steps as text
  1. user.hello() — there is an object before the dot, so this = user.
  2. const hello = user.hello copies only the function. The link to user is not copied.
  3. hello() — no object before the dot. In strict code, this = undefined, and reading this.name throws.
  4. hello.call(ravi) — you choose this explicitly.
  5. new Person('Mei') — new makes a fresh object and passes it as this.

Predict#

Predict first

const bound = hello.bind({ name: 'A' }); const obj = { name: 'B', bound }; What does obj.bound() return?

Interview angle#

Say it like this — about 30 seconds

“this is set by how a function is called. With new, it is the new object. With call, apply or bind, it is the value you pass. As a method, obj.fn(), it is obj. Otherwise it is undefined in strict code or the global object in sloppy code. That is also the precedence order. Arrow functions are the exception: they take this from the surrounding scope. Passing a method as a callback loses this because only the function is passed.”

Stays on your device. Nothing is uploaded.
Follow-up What is the difference between call, apply and bind?
call and apply call the function now — call takes arguments one by one, apply takes an array. bind returns a new function with this (and optionally some arguments) fixed.
Follow-up Why does const f = obj.method; f() lose this?
Assigning copies only the function. The later call has no object before the dot, so the default rule applies.
Follow-up How would you fix a method passed as a callback?
Pass obj.method.bind(obj), wrap it in an arrow — () => obj.method() — or define the method as an arrow class field (JS.03.02).

Practice#

On your own

Write bindAll(obj, ...names): replace each named method on obj with a version whose this is always obj.

Done when

  • A bound method still works when detached: const f = obj.m; f().
  • Arguments pass through, and methods not named are left alone.
  • It returns obj.
Your solution
Ctrl/⌘ + Enter

Remember#

Try to answer each card before you open it. Then add them to your reviews.

What decides the value of this?

How the function is called, not where it is written.

List the this rules from strongest to weakest.

new, then explicit (call/apply/bind), then method call, then default.

What is this in a plain call in strict code?

undefined.

Why does passing obj.method as a callback lose this?

Only the function is passed; it is later called without an object before the dot.

Go deeper

Four layers. Stop at the one your interview needs; each ends with a quick check.

The core ideaEvery round

Look at the call site. Something before the dot? That object is this. new? A new object. call/apply/bind? The value given. Nothing? undefined (strict).

Check yourself: In obj.a.b.fn(), what is this?

obj.a.b — the object directly before the last dot.

How it works underneathSenior rounds

obj.fn evaluates to a Reference Record that remembers its base, obj; calling it passes that base as thisValue Source: ECMA-262: EvaluateCall. Assigning to a variable reads only the function value, so the base is lost. In sloppy functions, an undefined this is replaced by the global object Source: ECMA-262: OrdinaryCallBindThis.

Check yourself: What spec value carries the object before the dot to the call?

A Reference Record, whose base value becomes thisValue.

Edge cases and trapsWhere people slip

Event listeners written as normal functions get the element as this. Normal-function callbacks to setTimeout in browsers get the global object as this, even in strict code, because the HTML Standard passes it. (0, obj.fn)() and (obj.fn = obj.fn)() lose this, but (obj.fn)() keeps it — parentheses alone do not change the reference.

Check yourself: What is this inside a DOM event listener written as a normal function?

The element the listener is attached to (event.currentTarget).

In productionStaff-level answers

Older React class components bound handlers in the constructor or used arrow class fields — both fixes for this exact problem. Libraries such as Lodash have bindAll. In modern code, prefer arrows and closures; reserve this for classes and methods.

Check yourself: Name two ways React class components kept this in handlers.

Binding in the constructor, or arrow-function class fields.

Finished the five steps? Mark it, and its cards join your reviews.

Last checked 2026-10-31. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.

Interview questions this answers

  • How is this determined in JavaScript? List the rules in order of precedence.
  • What is the difference between call, apply and bind?
  • Why does const f = obj.method; f() lose this?