The Magic of "this", "call()", "apply()", and "bind()" in JavaScript

In the previous blog, you learned how the this keyword works in JavaScript.
You saw that this is not fixed. It depends on how a function is called. It represents the caller of the function.
Now we take the next step.
What if you don’t want JavaScript to decide this for you?
What if you want to control it manually?
That is exactly where call(), apply(), and bind() come in.
A Quick Reminder About this
Before going deeper, let’s anchor the core idea again.
this refers to the object that is calling the function.
const user = {
name: "Shikhar",
greet: function() {
console.log(this.name);
}
};
user.greet(); // Shikhar
Here, user is calling the function, so this refers to user.
The Problem
Let’s slightly change the situation.
const user = {
name: "Shikhar",
greet: function() {
console.log(this.name);
}
};
const greetFn = user.greet;
greetFn();
Now the output becomes undefined.
The function is the same, but the caller changed.
So this changed.
This is where problems start in real applications.
The Solution
JavaScript gives you three methods to control this:
call()apply()bind()
All three allow you to decide what this should be.
What call() Does
call() lets you call a function immediately and explicitly set what this should be.
function greet() {
console.log(this.name);
}
const user = { name: "Shikhar" };
greet.call(user);
Output:
Shikhar
Here, even though greet is not inside user, we force this to be user.
Passing Arguments with call()
function greet(city) {
console.log(this.name + " from " + city);
}
greet.call(user, "Delhi");
What apply() Does
apply() works exactly like call().
The only difference is how arguments are passed.
function greet(city, country) {
console.log(this.name + " from " + city + ", " + country);
}
greet.apply(user, ["Delhi", "India"]);
Instead of passing arguments separately, you pass them as an array.
What bind() Does
bind() is slightly different.
It does not call the function immediately.
It returns a new function with this permanently set.
function greet() {
console.log(this.name);
}
const boundGreet = greet.bind(user);
boundGreet();
Why bind() is Useful
You can store the function and call it later without losing this.
This is very common in real-world applications.
Borrowing Methods (Real Use Case)
One of the most useful applications of call() and apply() is method borrowing.
const person1 = {
name: "Shikhar",
greet: function() {
console.log(this.name);
}
};
const person2 = {
name: "Rahul"
};
person1.greet.call(person2);
Output:
Rahul
Here, person2 is borrowing the method from person1.
Understanding the Difference Clearly
Here is the simplest way to remember:
| Method | Executes Immediately | How Arguments Are Passed | Returns Function |
|---|---|---|---|
| call | Yes | Separately | No |
| apply | Yes | As array | No |
| bind | No | Separately | Yes |
A Simple Mental Model
Think of it like this:
call()→ Call the function now with thisapply()→ Call the function now with this and array argumentsbind()→ Give me a new function with this fixed
Function and Caller Relationship
You can visualize it like this:
caller → function → this
Normally, JavaScript decides the caller.
With call, apply, and bind, you override it.
Real-World Example
function introduce(role) {
console.log(this.name + " is a " + role);
}
const user = { name: "Shikhar" };
introduce.call(user, "Developer");
introduce.apply(user, ["Engineer"]);
const intro = introduce.bind(user);
intro("Architect");
Common Mistakes
A common mistake is thinking that bind() executes the function immediately. It does not.
Another mistake is confusing call() and apply(). The only difference is how arguments are passed.
And finally, many developers forget that these methods exist and struggle with this issues that could be easily solved.
Final Thought
The this keyword is powerful, but it becomes even more powerful when you learn how to control it.
call(), apply(), and bind() give you that control.
Instead of relying on how a function is called, you decide what this should be.
That is when JavaScript starts feeling predictable.






