Set `this` Explicitly
JavaScript call, apply, bind
Three function methods that let you choose what `this` is when a function runs. `call` and `apply` invoke immediately; `bind` makes a new function.
What you'll learn
- Use `.call(thisArg, ...args)` to invoke with a chosen `this`
- Use `.apply(thisArg, argsArray)` — same, but args as array
- Use `.bind(thisArg)` to create a bound function
Every function comes with three built-in methods that let you control
this. They’re tools for the situations where the default this
rules don’t give you what you want.
call(thisArg, ...args)
Invokes the function with this set to thisArg. Arguments are
passed individually.
function greet(greeting) {
console.log(`${greeting}, ${this.name}!`);
}
const ada = { name: "Ada" };
greet.call(ada, "Hello"); // "Hello, Ada!"
greet.call(ada, "Hi"); // "Hi, Ada!" apply(thisArg, argsArray)
Same as call, but the arguments come as an array.
function describe(greeting, mood) {
console.log(`${greeting}, ${this.name}! Feeling ${mood}.`);
}
const ada = { name: "Ada" };
describe.apply(ada, ["Hi", "great"]); // "Hi, Ada! Feeling great." bind(thisArg, ...args) — Make a Bound Function
bind doesn’t call the function — it returns a new function
that, when called, has this permanently fixed.
function greet() {
console.log(`Hi, ${this.name}`);
}
const ada = { name: "Ada" };
const boundGreet = greet.bind(ada);
boundGreet(); // "Hi, Ada"
setTimeout(boundGreet, 0); // still "Hi, Ada" — bound stays bound bind is the classic fix for the “lost this” callback bug:
const user = {
name: "Ada",
greet() {
console.log(`Hi, ${this.name}`);
},
};
// Without bind — this is lost when setTimeout calls the function:
// setTimeout(user.greet, 10);
// With bind:
setTimeout(user.greet.bind(user), 10); // works In modern code, an arrow callback usually reads more clearly:
setTimeout(() => user.greet(), 10); Both work — pick the one that’s clearer in context.
Partial Application With bind
bind also lets you pre-fill arguments — known as partial
application.
function multiply(a, b) {
return a * b;
}
const double = multiply.bind(null, 2); // a = 2 pre-filled
const triple = multiply.bind(null, 3); // a = 3 pre-filled
console.log(double(10)); // 20
console.log(triple(10)); // 30 The null is thisArg; we’re not using this here so it doesn’t
matter.
Cheatsheet
| Method | Invokes now? | Args |
|---|---|---|
fn.call(this, …) | yes | individual |
fn.apply(this, []) | yes | array |
fn.bind(this, …) | no — returns new function | individual (partial OK) |
When You Actually Need These
In modern JavaScript, you’ll reach for call/apply/bind less
often — arrow functions and class have absorbed many of their use
cases. They still show up in:
- Library code that needs to manage
thiscarefully. - Borrowing methods from one type for another (
Array.prototype.slice.call(arguments)). - Partial application without a wrapper function.
Up Next
Functions as values — passing them, returning them, building with them.
JavaScript Higher-Order Functions →