call, apply & bind

Three ways to set this by hand -- invoke now with args, invoke now with an array, or make a permanently-bound copy.

Syntaxfn.call(thisArg, a, b) fn.apply(thisArg, [a, b]) const g = fn.bind(thisArg, a)

Every function inherits these three from Function.prototype. They all set this explicitly; they differ in when and how arguments arrive.

MethodCalls now?Arguments
callyeslisted one by one
applyyesa single array
bindno -- returns a new fnoptionally pre-filled
greet.call(user, 'Hi');
greet.apply(user, ['Hi']);
const boundGreet = greet.bind(user); // reusable, this locked to user

bind also does partial application

Arguments you pass to bind are pre-set on the new function, so const add5 = add.bind(null, 5) is a one-liner partial. And a bound function can never be re-bound -- its this is sealed.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Use bind to pre-set this on a class method before registering it as a DOM event listener.
  • Use apply to forward a variadic array of arguments to a function that expects individual parameters.
  • Use call to invoke a superclass method from a subclass override.

More examples

call with explicit this

call invokes total with order as this so this.prices resolves to order.prices.

Example · js
function total() {
  return this.prices.reduce((s, p) => s + p, 0);
}
const order = { prices: [10, 25, 5] };
console.log(total.call(order)); // 40

apply with argument array

apply spreads the args array as individual positional arguments, equivalent to log(...args).

Example · js
function log(level, source, message) {
  console.log(`[${level}] (${source}) ${message}`);
}
const args = ["ERROR", "db.js", "Connection refused"];
log.apply(null, args);

bind for stable event handler

bind permanently fixes this to the btn instance so handleClick works correctly as a DOM event listener.

Example · js
class Button {
  constructor(label) { this.label = label; }
  handleClick() { console.log("Clicked:", this.label); }
}
const btn = new Button("Submit");
const handler = btn.handleClick.bind(btn);
document.querySelector("button")?.addEventListener("click", handler);

Discussion

  • Be the first to comment on this lesson.
call, apply & bind — JavaScript | SoundsCode