What is the difference between call, apply, and bind?
All three let you set what this refers to inside a function. They differ in how arguments are passed and when the function runs.
call — invokes the function immediately, passing arguments one by one.
apply — invokes immediately, passing arguments as an array.
bind — returns a new function with this fixed, to call later.
Memory aid: call = Comma-separated args, apply = Array of args, bind = Bound for later.
function greet(greeting, punctuation) {
return `${greeting}, ${this.name}${punctuation}`;
}
const user = { name: 'John' };
// call — invoke immediately, args individually
console.log(greet.call(user, 'Hello', '!')); // 'Hello, John!'
// apply — invoke immediately, args as array
console.log(greet.apply(user, ['Hi', '?'])); // 'Hi, John?'
// bind — return new function, invoke later
const greetJohn = greet.bind(user, 'Hey');
console.log(greetJohn('.')); // 'Hey, John.' (partial application)
// Practical: borrowing methods
const arrayLike = { 0: 'a', 1: 'b', length: 2 };
const arr = Array.prototype.slice.call(arrayLike); // ['a', 'b']
// Practical: fixing this in callbacks
class Timer {
constructor() {
this.seconds = 0;
// bind fixes this in setInterval callback
setInterval(this.tick.bind(this), 1000);
// Or use arrow: setInterval(() => this.tick(), 1000);
}
tick() { this.seconds++; }
}call invokes immediately with individual args. apply invokes immediately with an array of args. bind returns a new function (does not invoke). bind with partial application: greet.bind(user, 'Hey') pre-fills the first argument. Method borrowing: Array.prototype.slice.call converts array-like objects. bind fixes this in callbacks (alternative to arrow functions).
call = invoke + individual args, apply = invoke + array args, bind = no invoke + return new function. The mnemonic: 'A for Array' (apply takes array). bind for fixing this in callbacks is the most practical use.
Method borrowing (Array.prototype.slice.call) shows advanced usage.