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

now we have one of the most important topic , now from here there is no going back , i will go very deep upto intervie level , if your attension spam is low this is not for you
JavaScript has many concepts that confuse beginners. One of the most misunderstood concepts is this.
Many memorize rules for this without actually understanding why it behaves the way it does. But the truth is much simpler:
this simply depends on who is calling the function.
Not who wrote it.
Not where it exists.
But who calls it.
Once you understand this idea, call(), apply(), and bind() suddenly start making sense.
In this article we will cover:
What
thismeans in JavaScriptthisinside normal functionsthisinside objectsWhat
call()doesWhat
apply()doesWhat
bind()doesDifference between
call,apply, andbindPractical examples with easy explanations
Everything will be explained step-by-step using simple objects and real examples.
Understanding this in JavaScript
Think of this as:
“The object that is calling the function.”
In other words:
thisrefers to the caller of the function
Example:
const person = {
name: "Dushyant",
greet: function () {
console.log("Hello " + this.name);
}
};
person.greet();
Output
Hello Dushyant
Let's understand what happened
We created an object called person.
Inside that object we created a method called greet.
Inside the method we used:
this.name
Now the key question is:
What does this refer to here?
Since the function was called like this:
person.greet()
The caller is person.
So:
this → person
Therefore:
this.name → person.name
Which becomes:
Hello Dushyant
this Inside Normal Functions
Now let's see what happens when a function is not inside an object.
function showName() {
console.log(this);
}
showName();
What happens here?
There is no object calling this function.
The function was called directly:
showName()
In a browser environment:
this → window object
So the output will be the global object.
But the important takeaway is:
If no object calls the function,
thisrefers to the global object.
this Inside Objects
Now let’s see a clearer example with objects.
const user = {
name: "Anita",
age: 22,
introduce: function () {
console.log("Hi, my name is " + this.name);
}
};
user.introduce();
Output
Hi, my name is Anita
Why?
Because the function is called like this:
user.introduce()
So:
this → user
And:
this.name → user.name
Which gives:
Anita
So remember this rule:
Inside objects, this refers to the object calling the method.
The Real Problem
Now imagine this situation.
We have two objects.
const person1 = {
name: "Dushyant",
greet: function () {
console.log("Hello " + this.name);
}
};
const person2 = {
name: "Shubhi"
};
Now we want person2 to use the same function.
But person2 doesn't have the greet method.
This is where call() comes in.
What call() Does
call() allows one object to borrow a method from another object.
Let’s see it in action.
const person1 = {
name: "Dushyant",
greet: function () {
console.log("Hello " + this.name);
}
};
const person2 = {
name: "Shubhi"
};
person1.greet.call(person2);
Output
Hello Shubhi
Let's break this down
The original function belongs to:
person1
But we used:
call(person2)
So we are telling JavaScript:
"Run this function, but pretend that person2 is calling it."
So:
this → person2
Therefore:
this.name → person2.name
Which gives:
Hello Shubhi
This is called method borrowing.
Using call() With Arguments
call() can also pass arguments.
Example:
const person = {
introduce: function (city, country) {
console.log(
"My name is " + this.name + " from " + city + ", " + country
);
}
};
const user = {
name: "Rohit"
};
person.introduce.call(user, "Delhi", "India");
Output
My name is Rohit from Delhi, India
Explanation
Here:
call(user, "Delhi", "India")
means:
this → user
city → Delhi
country → India
What apply() Does
apply() works almost the same as call().
The only difference is how arguments are passed.
call()
Arguments passed one by one
apply()
Arguments passed inside an array
Example:
const person = {
introduce: function (city, country) {
console.log(
"My name is " + this.name + " from " + city + ", " + country
);
}
};
const user = {
name: "Shubhansh"
};
person.introduce.apply(user, ["Indore", "India"]);
Output
My name is Shubhansh from Indore, India
Explanation
Here we used:
apply(user, ["Mumbai", "India"])
So JavaScript reads it like:
this → user
city → Mumbai
country → India
What bind() Does
bind() is slightly different.
call() and apply() run the function immediately.
But bind() does not execute the function immediately.
Instead:
bind()returns a new function withthispermanently set.
Example:
const person = {
name: "Dushyant",
greet: function () {
console.log("Hello " + this.name);
}
};
const user = {
name: "Anita"
};
const newFunction = person.greet.bind(user);
newFunction();
Output
Hello Anita
Explanation
Here we used:
bind(user)
But notice something important.
The function did not run immediately.
Instead:
bind() created a new function
That new function has:
this → user
Then when we ran:
newFunction()
It printed:
Hello Anita
Practical Assignment Example
Let's combine everything.
const student = {
name: "Dushyant",
introduce: function (course, year) {
console.log(
"Hi I am " + this.name +
", studying " + course +
" in year " + year
);
}
};
const anotherStudent = {
name: "Hanneta"
};
Using call()
student.introduce.call(anotherStudent, "Computer Science", 2);
Using apply()
student.introduce.apply(anotherStudent, ["Computer Science", 2]);
Using bind()
const introFunction = student.introduce.bind(anotherStudent);
introFunction("Computer Science", 2);
All three will produce:
Hi I am Hanneta, studying Computer Science in year 2
But the execution method is different.
Function → Caller Relationship
Function --------> Called by Object
|
v
this
Example:
person.greet()
Caller → person
this → person
Example with call:
person.greet.call(user)
Caller → user
this → user
Difference Between call, apply, and bind
| Feature | call() | apply() | bind() |
|---|---|---|---|
| Executes immediately | Yes | Yes | No |
| Returns new function | No | No | Yes |
| Arguments style | Normal arguments | Array arguments | Normal arguments later |
| Main purpose | Borrow function | Borrow function | Store function with fixed this |
When Should You Use Them?
Use call()
When you want to borrow a method and run it immediately.
Use apply()
When arguments already exist inside an array.
Use bind()
When you want to store a function and run it later with fixed this.
Very common in:
event handlers
callbacks
React components
timers




