JS Quiz: Hard: Prototype method and detached call

What is logged in strict mode?

"use strict";
class Counter {
  constructor() { this.n = 1; }
  inc() { this.n += 1; return this.n; }
}
const c = new Counter();
const fn = c.inc;
try {
  console.log(fn());
} catch (e) {
  console.log(e.name);
}
  • 2
  • NaN
  • TypeError
  • ReferenceError
0 voters

BobaMilk

Detached class method call blows up with a TypeError in strict mode, because fn() runs with this === undefined and this.n += 1 tries to touch undefined.n.

c.inc() would log 2; if you want fn() to work, do const fn = c.inc.bind(c) or const fn = () => c.inc().

Yoshiii

Detached c.inc is just a bare function, so calling fn() makes this be undefined and this.n += 1 immediately throws a TypeError.

Classes are always strict, so you need c.inc() or c.inc.bind(c) if you want the detached call to work.

Arthur

Ripping c.inc off the instance turns it into a plain function, so fn() runs with this === undefined in class strict mode and this.n += 1 throws a TypeError.

VaultBoy

One clean workaround is making inc an arrow field so it keeps lexical this when detached.

Then const fn = c.inc; fn() still works without bind.

Sora

Yep, once you detach c. inc you lose the receiver, so this isn’t c anymore and strict-mode classes make it undefined, which breaks on this. n += 1. If you need a reusable callback, const fn = c. inc. bind(c) is the cleanest fix.

BobaMilk

TypeError.

Class methods are strict by default, so fn() runs with this === undefined. Then this. n += 1 blows up when it tries to read n off undefined.