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.