← All concepts
A Closer Look at Functions

call, apply, and bind

Three ways to control what this refers to when a function runs.

Loading visual…

Definition

Every function has access to call, apply, and bind, three methods for controlling what `this` refers to inside it. `fn.call(thisArg, arg1, arg2)` invokes fn immediately, with `this` set to thisArg and the remaining arguments passed in one by one. `fn.apply(thisArg, [arg1, arg2])` does the same thing, invoking fn right away with `this` set to thisArg, but takes the arguments as a single array instead of a list, which is convenient when the arguments are already collected in an array or the count varies. `fn.bind(thisArg, arg1)` behaves differently: it does not call fn at all. Instead it returns a brand new function with `this` (and optionally some leading arguments) permanently locked to what was passed in, ready to be called later, as many times as needed, with `this` never changing again regardless of how that new function is eventually invoked. One exception applies to all three: arrow functions ignore call, apply, and bind for the purpose of setting `this`, because an arrow function has no `this` of its own, it always uses `this` from the scope where it was defined.

Examples

function greet() {
  return `Hi, ${this.name}`;
}
greet.call({ name: "Ada" });  // "Hi, Ada"
greet.apply({ name: "Ada" }); // "Hi, Ada"

call and apply both run greet immediately with this pointed at the given object. With no extra arguments, they behave the same here.

function introduce(greeting, punctuation) {
  return `${greeting}, ${this.name}${punctuation}`;
}
introduce.call({ name: "Grace" }, "Hello", "!");
introduce.apply({ name: "Grace" }, ["Hello", "!"]);
// both: "Hello, Grace!"

call takes the extra arguments individually, apply takes them as one array. Both produce the same result, only the argument shape differs.

function greet() {
  return `Hi, ${this.name}`;
}
const boundGreet = greet.bind({ name: "Alan" });
// nothing runs yet
boundGreet(); // "Hi, Alan", called later

bind returns a new function with this locked to the given object. The original greet is untouched, and boundGreet can be called anywhere, any number of times, always with the same this.

Where you see this

Practice this

Further reading