What they're testing
Whether you know this depends on the CALL SITE rather than the definition site, and when that causes bugs.
The short answer~30 seconds
In precedence order: with new, this is the newly created object; with call/apply/bind, it's what you passed; as a method call obj.fn(), it's obj; otherwise it's undefined in strict mode or the global object in sloppy mode. Arrow functions opt out: they take this from the enclosing scope at definition time, and bind can't change it.
The long answer
The classic bug is losing this when a method is passed as a callback: setTimeout(obj.method, 0) calls the function with nothing in front of it, so this is no longer obj. Three fixes: bind at the call site, wrap in an arrow, or declare the class field as an arrow. They cost differently — bind creates a new function each time, which in React is a routine cause of needless re-renders.
The converse matters just as much: an arrow function is NOT usable as an object method when you need this to be that object, and can't be a constructor. It also has no arguments. So the good answer isn't "arrows are better" but "arrows solve the lost-context problem specifically, and create a different one when used in the wrong place".
const timer = {
seconds: 0,
startBroken() {
setInterval(function () { this.seconds++; }, 1000);
// `this` là undefined (strict) — hàm được gọi trần
},
startWorking() {
setInterval(() => { this.seconds++; }, 1000);
// arrow lấy `this` của startWorking, tức là `timer`
},
};
const { startWorking } = timer;
startWorking(); // vẫn hỏng: mất object phía trước khi gọiWhat they'll ask next
?call vs apply vs bind?
call and apply invoke immediately, differing only in how arguments are passed (list versus array). bind doesn't invoke — it returns a new function with this fixed, and once fixed it can't be rebound; a second bind does nothing.
These lose points
- Saying "
thisis the current object". There is no current object — only the way the function was called.