All three methods are used to control the value of this when calling a function. The difference is how they pass arguments and when the function is executed. These affect this-binding and performance, so test with bound handlers and avoid unnecessary allocations.
What is the difference between call(), apply(), and bind() in JavaScript?
Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.
The Core Idea
In JavaScript, functions are special objects — they have built-in methods like call(), apply(), and bind() that allow you to explicitly set what this refers to when a function runs.
They all help you reuse a function with different objects as its this context.
Method | When It's Executed | How Arguments Are Passed | Return Value |
|---|---|---|---|
| Immediately | As a comma-separated list | Return value of the function |
| Immediately | As an array (or array-like) | Return value of the function |
| Later (creates a new function) | As a comma-separated list | New function with bound context |
Example Setup
Let's start with a simple function that uses this:
const person = { name: 'Alice' };
function greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
1. call()
call() invokes the function immediately and passes arguments one by one.
greet.call(person, 'Hello', '!'); // Hello, Alice!
2. apply()
apply() is just like call(), but it takes arguments as an array.
greet.apply(person, ['Hi', '!!']); // Hi, Alice!!
3. bind()
bind() does not run the function immediately. Instead, it returns a new function with a permanently bound this value.
const greetAlice = greet.bind(person, 'Hey');
greetAlice('!!!'); // Hey, Alice!!!
Common Mistake
A frequent confusion is expecting bind() to call the function immediately. Remember: it only returns a new function — you have to call it manually later.
const fn = greet.bind(person, 'Hello');
fn('!'); // Works
// greet.bind(person, 'Hello')('!') also works
Practical scenario
Borrow a method from another object (e.g., Array.prototype.slice) or fix this in a callback.
Common pitfalls
- Forgetting to bind, causing
thisto beundefinedin strict mode. - Using
applywith very large arrays and hitting argument limits. - Binding inside render loops and creating new functions each time.
bind is clear but allocates a new function; reuse bound handlers where possible. Test by calling the function with a mocked this.Think of it like renting a car:
- call() → You rent and drive it right away.
- apply() → You rent and drive it right away, but hand over your passengers list (array).
- bind() → You book it for later — the car is reserved and ready to use when you need it.
- call() → Calls immediately, arguments as a list.
- apply() → Calls immediately, arguments as an array.
- bind() → Returns a new function (call it later).
All three methods let you control what this refers to.