Q21 of 40 · JavaScript

What is the difference between `call()`, `apply()`, and `bind()`?

JavaScriptMidjavascriptcallapplybindthisfunctional

Short answer

Short answer: All three explicitly set `this`. `call(ctx, arg1, arg2)` invokes immediately with individual args. `apply(ctx, [args])` invokes immediately with an array. `bind(ctx, ...args)` returns a new pre-bound function for later invocation — useful for callbacks and partial application.

Detail

These three Function.prototype methods give you explicit control over this binding and argument passing.

call(): fn.call(thisArg, arg1, arg2, ...). Invokes fn immediately with this set to thisArg and individual comma-separated arguments.

apply(): fn.apply(thisArg, [arg1, arg2, ...]). Same as call but arguments are passed as an array. Historically useful before spread syntax; fn(...arr) now often replaces fn.apply(null, arr).

bind(): const bound = fn.bind(thisArg, ...partialArgs). Returns a new function with this permanently bound. Optional partial arguments are prepended every time it's called — making it also a partial application tool.

Partial application: const double = multiply.bind(null, 2) creates a function that always passes 2 as the first argument. Useful for creating specialised helpers from general functions.

In test automation: bind is used to pass class methods as event handlers or Playwright hooks without losing context.

// EXAMPLE

function greet(greeting, punctuation) {
  return `${greeting}, ${this.name}${punctuation}`;
}
const user = { name: "Alice" };

greet.call(user, "Hello", "!");  // "Hello, Alice!"
greet.apply(user, ["Hi", "."]);  // "Hi, Alice."

const boundGreet = greet.bind(user, "Hey");
boundGreet("?");                  // "Hey, Alice?"

// Preserve 'this' when passing as callback
class Logger {
  prefix = "[LOG]";
  log(msg) { console.log(`${this.prefix} ${msg}`); }
}
const logger = new Logger();
// logger.log passed as callback without bind → 'this' is undefined
[1, 2, 3].forEach(logger.log.bind(logger)); // works correctly

// WHAT INTERVIEWERS LOOK FOR

Clear call vs apply vs bind distinction. The key point that bind returns a new function while call/apply invoke immediately. Partial application as a bonus use case. Connecting to callback context preservation.

// COMMON PITFALL

Using bind on an arrow function — arrow functions ignore explicit `this` binding (lexical `this` always wins), so bind has no effect on `this` for arrows. It still pre-fills arguments, though.