Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Using the `this` Keyword  ›  Lesson

this in Arrow Functions

in arrow functions 12 minAn arrow function has no this of its own; it uses this from the scope it was written in, unaffected by how the arrow itself is later called, which makes it the natural fix for a callback that needs its outer method's this.

this in Arrow Functions

In short: an arrow function has no this of its own. Wherever you write this inside an arrow, it looks outward to the this of the scope the arrow was written in — fixed at that point, permanently. This makes arrows the natural fix for a callback that needs its enclosing method's this: a regular function callback gets its own fresh this (usually not what you want), but an arrow simply keeps using the this that was already in scope around it.

playEach(list) { ... } — this = song, containing two callbacks: list.forEach(function (s) { this.title // NOT song! }) — regular function, own new this; list.forEach((s) => { this.title // song.title! }) — arrow, locked to playEach's this; a dashed lock arrow points from the arrow callback back up to playEach — call, apply and bind cannot change an arrow's this either

Keep this working inside forEach

A regular function passed to forEach is called as a plain function, so it gets its own this — not the enclosing method's. An arrow function in the same spot keeps the method's this:

javascript

The regular function's this is undefined (strict mode, called standalone by forEach), so this && this.title short-circuits to undefined. The arrow function never asks "what was I called with?" — it simply uses playEach's own this, which is song, so it logs "Blue Hour".

Confirm the arrow's this never changes

Because an arrow's this is fixed at the point it was written, not at the point it's called, even call, apply and bind — which exist specifically to set this — have no effect on it:

javascript

All three lines print "Blue Hour". arrow was created inside make(), where this was outer — that's locked in forever. .call(other) and .bind(other) try to supply other as this, but an arrow function never reads a this from how it's called in the first place, so there is nothing for them to override.

The trap: an arrow as an object's own method

Because an arrow's this comes from its surrounding scope, writing one directly as an object's method usually backfires — at the point the object literal is written, this isn't the object being built yet:

javascript

This logs undefined — play's this is whatever this was in the surrounding code where the object literal itself was written, never song. (The this && guard just avoids crashing if that surrounding this happens to be undefined — its value depends on where the object literal sits, which is exactly the point: it's not song.) Use a regular method (play() { ... }) for an object's own methods; save arrows for callbacks inside a method, where borrowing the method's this is exactly what you want.

Quick practice

quick drill

What this does an arrow function use, when this appears inside it?

quick drill

Inside a method, list.forEach(function (s) { this.title }) vs list.forEach((s) => { this.title }) — which keeps the method's this?

quick drill

Can .call() or .bind() change what this an arrow function uses?

quick drill

Why is writing an arrow function directly as an object's method usually a mistake?

quick drill

When is an arrow function the right tool for this-handling?

🎯 Your turn

Explain why list.forEach(function (s) { console.log(this.title); }) inside a method loses this, while list.forEach((s) => { console.log(this.title); }) in the exact same spot does not, and why call/apply/bind cannot change an arrow function's this.

Write your explanation and submit it — there's no code to run here, just your reasoning.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainFix the lost this

Explain why list.forEach(function (s) { console.log(this.title); }) inside a method loses this, while list.forEach((s) => { console.log(this.title); }) in the exact same spot does not, and why call/apply/bind cannot change an arrow function's this.