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

If you’ve spent some time learning JavaScript, you’ve probably come across the keyword this and had a thought about what it actually refers to.
Sometimes it points to an object. Sometimes it seems to behave differently depending on how a function is called. This flexibility can feel confusing at first, but the idea behind it is actually simple.
A good way to understand this is to think about who is responsible for running the function.
In many situations, this simply refers to the object that calls the function. Once that idea clicks, the rest of the concepts—like call(), apply(), and bind(), start to make much more sense.
Let’s explore how it works.
What "this" Means in JavaScript
In JavaScript, The keyword this refers to the current object that is executing the function.
Think of it like : “Who is calling this function right now?”
A simpler way to remember this is:
thisusually refers to the object that called the function.
Here’s a simple example.
let person = {
name: "Alice",
greet: function() {
console.log("Hello, my name is " + this.name);
}
};
person.greet();
Output:
Hello, my name is Alice
When greet() runs, it is called by the person object:
The object
personcalled the functionSo
thisrefers to person
"this" Inside Normal Functions
If a function is being called on it's own, instead of being called through an object, it behaves differently.
In a regular standalone function, this usually refers to the global object (or undefined in strict mode).
Example:
function show() {
console.log(this);
}
show();
Here, this does not refer to any specific object because the function was called directly.
This is why this is more useful when working with objects.
"this" Inside Objects
Inside objects, this refers to the object that owns the method.
Example:
let car = {
brand: "Toyota",
showBrand: function() {
console.log(this.brand);
}
};
car.showBrand();
Output:
Toyota
Here, the showBrand method is called by the car object. That means this points to car, allowing the method to access car.brand.
this.brand ---> car.brand
What call() Does
JavaScript includes methods that allow you to control what this refers to.
One of these is call().
The call() method allows you to borrow a function from one object and use it with another object.
Example:
let person1 = {
name: "Rahul"
};
let person2 = {
name: "Anita"
};
function greet() {
console.log("Hello " + this.name);
}
greet.call(person1);
greet.call(person2);
Output:
Hello Rahul
Hello Anita
Here, the same function is used with different objects. call() temporarily assigns the object as the context for this.
call() lets us manually choose what this should refer to.
What apply() Does
The apply() method works almost the same way as call(), but there is one small difference in how arguments are passed.
With apply(), arguments are provided inside an array.
Example:
function introduce(city, country) {
console.log(this.name + " lives in " + city + ", " + country);
}
let person = {
name: "Rahul"
};
introduce.apply(person, ["Delhi", "India"]);
Output:
Rahul lives in Delhi, India
So while both methods allow you to set this, the only real difference is how the arguments are passed.
call() → arguments passed separately
apply() → arguments passed as an array
What bind() Does
Unlike call() and apply(), the bind() method does not immediately run the function.
Instead, it creates a new function where this is permanently set to a specific object.
Example:
let person = {
name: "Rahul"
};
function greet() {
console.log("Hello " + this.name);
}
let greetUser = greet.bind(person);
greetUser();
Output:
Hello Rahul
In this case, bind() produces a new function that always treats person as this, no matter where the function is used later.
Difference Between call(), apply(), and bind()
These three methods are closely related but serve slightly different purposes.
| Method | Behavior | Arguments |
|---|---|---|
| call() | Runs the function immediately | Arguments passed individually |
| apply() | Runs the function immediately | Arguments passed as an array |
| bind() | Returns a new function | Arguments provided later |
Example comparison:
func.call(obj, arg1, arg2);
func.apply(obj, [arg1, arg2]);
let newFunc = func.bind(obj);




