5.4 — this: the compass
Every function you’ve written since Phase 3 has quietly avoided one keyword: this. Here’s its full, precise story — and it fits in one sentence that most JavaScript developers never learn precisely: this is decided at CALL time, by HOW the call is made. Not by where the function is written. Not by which object "owns" it. By the call.
Today's proof is the plainest kind: ONE small function, whoAmI, never changes for the whole lesson. We're going to call it four different ways and watch a table fill in — same function, four rows, four different answers. Four rules cover every row — and one function kind (arrows) that plays by a completely different rule. Learn the four, and a whole genre of interview questions becomes mechanical.
function whoAmI() {
return this.name;
}
const cat = { name: "Biscuit" };
cat.speak = whoAmI;
cat.speak();
const loose = cat.speak;
loose();
const bound = whoAmI.bind({ name: "Rex" });
bound();Here is ONE small function, unchanged for the rest of this lesson: whoAmI returns this.name. Read its body all you like — it cannot tell you what this.name will be, because this has no value until the function is actually CALLED. We’re about to call this exact function several different ways and watch a table fill in below, one row per call.
The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”
Why does the default rule sometimes give the global object and sometimes undefined? Strict mode — a per-file/function opt-in ("use strict") that modern tooling and class bodies enable automatically. Sloppy mode papers over the lost-this bug with the global object. Strict mode surfaces it as TypeError: Cannot read properties of undefined. Same philosophy as 5.2's TDZ: loud beats silent.
The rules compose with everything you know. this is stored per execution context — each call's context gets its own. Arrows don't create a this in their context, so they fall back to the rope.
And the table's whole point is honest: the same function object can be attached to different owners freely. Borrow a method with a.speak = b.speak — the dot rule follows whoever calls.
💼 On the job — Playwright test code uses arrows almost everywhere precisely to avoid this entire topic. But Page Object classes (11.9) use this.page constantly, via the implicit and new rules. You'll use all four rules weekly; you'll debug rule 2 (lost this) at least once in your career. Today means you'll recognize it in seconds.
⌨️ the announcer that never loses its team
Build a method that works through the dot — then make a detached copy that STILL works, by welding its this before handing it off.
requirements:
- An object
teamwithname="Rockets"and a methodannounce()that prints"Go " + this.name + "!". - Call it through the dot once.
- Now create
shout— a detached, SAFE copy of the method whosethisis permanently pointed atteam— and callshout()bare. It must still print the same line.
when you press RUN, the console must show exactly:
✏️ Quick check 1
Type exactly what this prints:
const drum = {
sound: "boom",
hit() {
console.log(this.sound);
},
};
drum.hit();✏️ Quick check 2
Type exactly what this prints:
function who() {
console.log(this.label);
}
const tagged = who.bind({ label: "A7" });
tagged();✏️ Quick check 3
this is decided at ___ time — type: write or call.
🗣️ Now teach it back
The interview question: “Explain this in JavaScript.” Give the one-sentence core, the four rules in priority order, the arrow-function exception — and name the classic bug the default rule causes.
Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.