Master call, apply, bind in Three Sentences
All three methods do the same thing: forcibly bind a function’s this to a value you specify. They differ only in argument style and execution timing.
call — executes immediately, comma-separated arguments
fn.call(thisArg, arg1, arg2, arg3);
function greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
const user = { name: "Alice" };
greet.call(user, "Hello", "!"); // "Hello, Alice!"
apply — executes immediately, arguments in an array
The only difference from call is that arguments go inside an array:
fn.apply(thisArg, [arg1, arg2, arg3]);
greet.apply(user, ["Hi", "?"]); // "Hi, Alice?"
Which one to choose? Arguments already in an array → apply; scattered arguments → call. They are functionally equivalent.
bind — does NOT execute, returns a new function with this locked in
const boundFn = fn.bind(thisArg, arg1, arg2);
// Doesn't execute! Returns a new function with this permanently bound
const greetAlice = greet.bind(user, "Hey");
greetAlice("!!"); // "Hey, Alice!!"
bind does not mutate the original function — it produces a new function whose this is locked forever. Typical use cases: callbacks, event handlers.
Arrow functions have no own
this, so these three methods have no effect on them. See Arrow Functions andthisfor details.