Skip to content

Quiz: Predict the Output — this

intermediate8 min read

Test Your this Binding Mastery

Think you've got this figured out? Let's find out. For each question, apply the four rules in priority order: new > explicit (call/apply/bind) > implicit (dot) > default (plain call). Remember that arrow functions don't follow these rules — they inherit this lexically.

All examples run in strict mode (default this is undefined, not globalThis). Don't just guess — trace the rules step by step.


Question 1: The Basic Dot Rule

"use strict";
const obj = {
  name: "Alice",
  getName() {
    return this.name;
  }
};

const fn = obj.getName;
console.log(fn());
Quiz
What does fn() output?

Question 2: Arrow in an Object

"use strict";
const obj = {
  name: "Alice",
  getName: () => {
    return this.name;
  }
};

console.log(obj.getName());
Quiz
What does obj.getName() output?

Question 3: Arrow Inside a Method

"use strict";
const obj = {
  name: "Alice",
  greet() {
    const inner = () => this.name;
    return inner();
  }
};

console.log(obj.greet());
Quiz
What does obj.greet() output?

Question 4: Bind vs Call Priority

This one trips up even senior devs.

"use strict";
function showName() {
  return this.name;
}

const bound = showName.bind({ name: "Bound" });
console.log(bound.call({ name: "Called" }));
Quiz
What does bound.call({ name: 'Called' }) return?

Question 5: New vs Bind

"use strict";
function Person(name) {
  this.name = name;
}

const BoundPerson = Person.bind({ name: "Bound" });
const p = new BoundPerson("Alice");
console.log(p.name);
Quiz
What does p.name return?

Question 6: Callback Context Loss

"use strict";
class Timer {
  constructor() {
    this.count = 0;
  }
  increment() {
    this.count++;
  }
  start() {
    // Passing this.increment as a callback
    [1, 2, 3].forEach(this.increment);
  }
}

const t = new Timer();
t.start();
Quiz
What happens when t.start() is called?

Question 7: Nested Method Calls

"use strict";
const a = {
  name: "A",
  inner: {
    name: "B",
    getName() {
      return this.name;
    }
  }
};

const fn = a.inner.getName;
console.log(a.inner.getName());
console.log(fn());
Quiz
What are the two outputs?

Question 8: setTimeout and Arrow Functions

Last one. This combines everything you've learned.

"use strict";
const obj = {
  value: 42,
  delayedLog() {
    setTimeout(function() {
      console.log("regular:", this?.value);
    }, 0);
    setTimeout(() => {
      console.log("arrow:", this.value);
    }, 0);
  }
};

obj.delayedLog();
Quiz
What gets logged (in order)?

Scoring Guide

ScoreAssessment
8/8You can trace this-binding in your sleep. Staff-engineer level.
6-7Strong grasp. Review the arrow function and extraction edge cases.
4-5The four rules are clear but the interactions (bind + call, new + bind) need work.
0-3Revisit the this-binding rules lesson. Focus on the priority order and arrow function behavior.
Key Rules
  1. 1Priority: new > explicit (call/apply/bind) > implicit (obj.method()) > default (plain call)
  2. 2Arrow functions ignore all four rules — they capture this from where they are DEFINED
  3. 3Method extraction (assigning obj.method to a variable) always loses implicit binding
  4. 4bind is permanent — call and apply cannot override it. Only new can.
  5. 5In strict mode, default this is undefined. In sloppy mode, it's globalThis.