call
Runs the function now. Pass arguments one by one.
All three control what this means inside a regular function. The difference is when the function runs and how you pass its arguments.
callRuns the function now. Pass arguments one by one.
applyRuns the function now. Pass arguments in an array or array-like object.
bindReturns a new function for later. It can also prefill arguments.
| Method | Shape | Runs now? | Result |
|---|---|---|---|
call | fn.call(thisArg, a, b) | Yes | Function's return value |
apply | fn.apply(thisArg, [a, b]) | Yes | Function's return value |
bind | fn.bind(thisArg, a, b) | No | A new function |
thisFor a regular function, this usually depends on how the function is called. Pulling a method away from its object also pulls away the call-site context.
const account = {
owner: "Mira",
introduce() {
return `I am ${this.owner}`;
}
};
account.introduce(); // "I am Mira"
const introduce = account.introduce;
introduce(); // `this` is no longer `account`
The question to ask: what value sits to the left of the dot at the call site? Explicit methods such as call, apply, and bind let you supply that value yourself.
The first argument becomes this. Every later argument goes to the function in order.
function describe(role, punctuation) {
return `${this.name} is a ${role}${punctuation}`;
}
const person = { name: "Asha" };
describe.call(person, "designer", "!");
// "Asha is a designer!"
apply is handy when the arguments already live in an array. Modern spread syntax often reads more naturally when no custom this value is needed.
With apply
const scores = [18, 31, 24];
Math.max.apply(null, scores);
// 31
With spread syntax
const scores = [18, 31, 24];
Math.max(...scores);
// 31
bind does not call the original function. It creates a new function whose this value is fixed.
const user = {
name: "Dev",
greet() {
console.log(`Hello, ${this.name}`);
}
};
const greetDev = user.greet.bind(user);
setTimeout(greetDev, 100);
// "Hello, Dev"
bind can prefill arguments. This is partial application.function multiply(a, b) {
return a * b;
}
const double = multiply.bind(null, 2);
double(7); // 14
A function does not belong permanently to the object where it was defined. call can run it with another compatible object as this.
const member = {
firstName: "Nikhil",
fullName() {
return `${this.firstName} ${this.lastName}`;
}
};
const guest = { firstName: "Rhea", lastName: "Sen" };
member.fullName.call(guest);
// "Rhea Sen"
Arrow functions do not create their own this. They capture it from the surrounding scope, so call, apply, and bind cannot replace it.
const showName = () => this.name;
showName.call({ name: "Asha" });
// not "Asha"
call later.call has already run the function. Use bind when an event handler or timer needs a function.
call.fn.call(obj, [1, 2]) passes one array argument. Use apply or spread when the function expects two arguments.
Use a regular function when the caller should control this.
bind. It creates a new function with fixed context and optional prefilled arguments.
fn.call(obj, 1, 2) and fn.apply(obj, [1, 2])?
Both run immediately with obj as this. call takes separate arguments, while apply takes one array-like collection.
bind change the this value captured by an arrow function?
No. An arrow function gets this from the scope where the arrow was created.