JavaScript Interview Prep
this Keyword & Binding

Arrow Functions & this

Why Arrows Have No Reflection

LinkedIn Hook

An arrow function walks into an object. It has no reflection.

That's the mental model: arrow functions don't carry their own this. They look UP, not in. They borrow this from whatever scope was surrounding them when they were written — and they keep that choice forever.

This is why call, apply, and bind silently fail on arrows. It's why setInterval(() => this.seconds++, 1000) magically works inside a method, but a regular function version does not.

Lexical this is one of ES6's quietest superpowers — and one of the fastest ways to confuse yourself if you don't know it.

In this lesson I show exactly when arrows save you, when they betray you, and the object-literal trap that surprises almost everyone.

Read the full lesson -> [link]

#JavaScript #InterviewPrep #ArrowFunctions #LexicalThis #ES6 #CodingInterview #Frontend


Arrow Functions & this thumbnail


What You'll Learn

  • Why arrow functions never own their own this and always inherit it lexically
  • Why call, apply, and bind have zero effect on an arrow function
  • The callback scenarios where arrows save you — and the object-literal trap where they bite you

Arrow Functions Don't Have Their Own this

Arrow functions are like mirrors — they don't have their own reflection (this). Instead, they reflect whatever this exists in their surrounding (enclosing) scope. This is called lexical binding.

const obj = {
  name: "Rakibul",
  regularFunc: function() {
    console.log("Regular:", this.name); // "Rakibul"
  },
  arrowFunc: () => {
    console.log("Arrow:", this.name); // undefined (this = enclosing scope, which is global/module)
  }
};

obj.regularFunc(); // "Regular: Rakibul"
obj.arrowFunc();   // "Arrow: undefined"

Why? The arrow function is defined inside the object literal. But an object literal does NOT create a new scope — so the enclosing scope is the global/module scope, not the object.

Where Arrow Functions Shine — Callbacks

const timer = {
  seconds: 0,
  start: function() {
    // Regular function in setInterval — 'this' would be lost!
    setInterval(function() {
      this.seconds++; // 'this' is window/undefined, NOT timer
      console.log(this.seconds); // NaN
    }, 1000);
  }
};

// Fixed with arrow function
const timerFixed = {
  seconds: 0,
  start: function() {
    setInterval(() => {
      this.seconds++; // Arrow inherits 'this' from start(), which is timerFixed
      console.log(this.seconds); // 1, 2, 3, ...
    }, 1000);
  }
};

Arrow Functions Cannot Be Rebound

const arrowFn = () => {
  console.log(this);
};

const obj = { name: "Rakibul" };

// None of these will change 'this' for an arrow function
arrowFn.call(obj);    // still global/undefined
arrowFn.apply(obj);   // still global/undefined
const bound = arrowFn.bind(obj);
bound();               // still global/undefined

Lexical this in Nested Functions

const team = {
  name: "Alpha",
  members: ["Rakibul", "Karim", "Sadia"],
  showMembers: function() {
    // Arrow function inherits 'this' from showMembers
    this.members.forEach((member) => {
      console.log(member + " belongs to " + this.name);
    });
  }
};

team.showMembers();
// "Rakibul belongs to Alpha"
// "Karim belongs to Alpha"
// "Sadia belongs to Alpha"

Arrow Functions & this visual 1


Common Mistakes

  • Defining a method as an arrow function directly on an object literal (e.g., greet: () => this.name) and expecting this to be the object — it isn't; the object literal has no scope, so this falls through to global/module.
  • Using .call(obj) / .apply(obj) / .bind(obj) on an arrow function expecting this to change — arrows ignore all three.
  • Using an arrow function as a constructor (e.g., new MyArrow()) — arrows have no [[Construct]] and throw TypeError: MyArrow is not a constructor.

Interview Questions

Q: Do arrow functions have their own this?

No. Arrow functions do not have their own this binding. They inherit this from the enclosing lexical scope at the time they are defined. This is called lexical this binding.

Q: Can you use call, apply, or bind to change the this of an arrow function?

No. Since arrow functions don't have their own this, these methods have no effect on them. The this value is permanently determined by the enclosing scope.

Q: Why are arrow functions useful in callbacks?

Callbacks like setTimeout, setInterval, or array methods (forEach, map) normally lose the this context. Arrow functions solve this because they capture this from the enclosing scope, so there's no loss.

Q: What is lexical this?

Lexical this means the value of this is fixed based on WHERE the function was written (its enclosing scope), not HOW it is called. Arrow functions use lexical this; regular functions do not.

Q: What does this refer to in an arrow function defined inside an object literal?

It refers to this from the surrounding scope — typically the global object in non-strict browser code, or undefined/module scope in strict/ESM contexts. Object literals do not create their own scope, so the arrow does NOT bind to the object.


Quick Reference — Cheat Sheet

ARROW FUNCTIONS & this — QUICK MAP

Arrow                -> no own this
                        this = enclosing lexical scope (fixed forever)

call / apply / bind  -> IGNORED on arrows
new MyArrow()        -> TypeError (arrows can't be constructors)

Good use cases:
  setTimeout(() => this.x, 1000)
  arr.forEach(item => this.handle(item))
  Promise chains inside a method

Trap:
  { greet: () => this.name }   // this = global, NOT the object!
  Object literals do NOT create scope.

Fix for method:
  { greet: function() { return this.name; } }
  or shorthand:
  { greet() { return this.name; } }

Previous: new Binding -> The 4-Step Factory Next: Binding Priority & Lost this


This is Lesson 4.4 of the JavaScript Interview Prep Course — 14 chapters, 87 lessons.

On this page