Question presented to candidate: "What's the actual difference between call, apply, and bind — not just how their arguments are formatted, but what each one actually DOES to the function?"
What a strong answer should cover:
- 📌 Interview term:
fn.call(thisArg, arg1, arg2, ...)— invokesfnimmediately, withthisset tothisArg, passing the remaining arguments individually. - 📌 Interview term:
fn.apply(thisArg, [arg1, arg2, ...])— invokesfnimmediately, identical tocall, except the arguments are passed as a single array. - 📌 Interview term:
fn.bind(thisArg, arg1, ...)— does not invokefnat all; it returns a new function withthispermanently locked tothisArg(and optionally some leading arguments pre-filled), to be called later. - 📌 Interview term: the real, direct distinguishing proof — verified directly: calling
.call()/.apply()genuinely invoked the function immediately (a tracking flag flipped totruesynchronously), while calling.bind()genuinely left that same flagfalseuntil the returned bound function was separately, explicitly called. - A precise answer names that once a function is bound, its
thisgenuinely cannot be overridden by a later.call(),.apply(), or even another.bind()— verified directly, the original boundthisstayed in place through both override attempts — and that arrow functions ignore all three methods'thisargument entirely, since arrow functions have nothisof their own to rebind.
Clarifying questions expected:
- None — this is a definitional/comparison question; correctly distinguishing "invokes immediately" (call/apply) from "returns a new function for later" (bind) is the strong signal, beyond the argument-formatting difference most candidates already know.
Code / implementation expected: Yes — demonstrating the immediate-invocation vs. deferred-invocation distinction directly (not just the argument format) is the most convincing proof of real understanding.