Understanding this, call(), apply(), and bind() in JavaScript

JavaScript provides a special keyword called this that plays an important role in how functions access data. Many beginners find it confusing because its value changes depending on how a function is called.
In this article, we will understand what this means in JavaScript and how functions like call(), apply(), and bind() help us control it. Instead of diving into complex internal mechanics, we will focus on the practical idea of “who is calling the function.”
Once you understand this idea, the behavior of this becomes much easier to reason about.
What this Means in JavaScript
In JavaScript, the value of this depends on the object that calls the function.
A simple way to remember this is:
this refers to the object that is calling the function.
Let us start with a simple example.
function greet() {
console.log(this);
}
greet();
When this function runs in the browser, this usually refers to the global object (window). In Node.js it refers to the global environment object.
This happens because the function is called directly, not by any object.
So the caller of the function is the global environment.
this Inside Normal Functions
When a normal function is called by itself, there is no specific object calling it. In such cases, JavaScript assigns the global context.
Example:
function showName() {
console.log(this.name);
}
var name = "Rahul";
showName();
Output
Rahul
Here the variable name exists in the global scope. Since the function is called normally, this refers to the global object, so this.name resolves to the global variable.
This behavior can sometimes cause confusion, which is why developers usually prefer calling functions through objects when they rely on this.
this Inside Objects
When a function is defined as a method of an object and that object calls the function, this refers to that object.
Example:
const person = {
name: "Amit",
greet: function () {
console.log("Hello " + this.name);
}
};
person.greet();
Output
Hello Amit
In this case the function greet() is called by person, so this refers to the person object.
You can visualize this relationship like this:
Function ← called by ← Object
greet() person
this → person
The important point is that the caller determines the value of this.
The Problem: Losing the Original Caller
Sometimes we want to use a method from one object inside another object. This is called function borrowing.
Consider the following example.
const person1 = {
name: "Rahul",
greet: function () {
console.log("Hello " + this.name);
}
};
const person2 = {
name: "Anita"
};
Now suppose we want person2 to use the greet() method from person1.
This is where call(), apply(), and bind() become useful.
What call() Does
The call() method allows us to manually set the value of this while calling a function.
Syntax
functionName.call(object, arg1, arg2)
Example:
person1.greet.call(person2);
Output
Hello Anita
Even though the function belongs to person1, we explicitly tell JavaScript that this should refer to person2.
So the method runs using the data of person2.
Example with arguments:
function introduce(city, country) {
console.log(this.name + " from " + city + ", " + country);
}
const user = {
name: "Riya"
};
introduce.call(user, "Delhi", "India");
Output
Riya from Delhi, India
Here the first argument sets this, and the remaining arguments are passed normally.
What apply() Does
The apply() method works almost the same as call(). The only difference is how arguments are passed.
Syntax
functionName.apply(object, [arg1, arg2])
Arguments are passed as an array.
Example:
introduce.apply(user, ["Mumbai", "India"]);
Output
Riya from Mumbai, India
Both call() and apply() execute the function immediately. The main difference lies in the argument format.
What bind() Does
Unlike call() and apply(), the bind() method does not execute the function immediately.
Instead, it creates a new function with a fixed this value.
Syntax
const newFunction = functionName.bind(object)
Example:
const greetUser = person1.greet.bind(person2);
greetUser();
Output
Hello Anita
Here bind() returns a new function where this is permanently set to person2.
This is very useful when passing functions as callbacks.
Difference Between call, apply, and bind
The following comparison helps summarize the behavior.
| Method | Executes Immediately | Argument Format | Returns New Function |
|---|---|---|---|
| call | Yes | Arguments passed individually | No |
| apply | Yes | Arguments passed as an array | No |
| bind | No | Arguments passed individually | Yes |
Another way to think about it:
call()→ run the function nowapply()→ run the function now with array argumentsbind()→ create a new function for later use
Assignment
Try implementing the following small exercise.
Create an object with a method that uses this.
Example structure:
const student = {
name: "Arjun",
showName: function () {
console.log(this.name);
}
};
Create another object.
const student2 = {
name: "Meera"
};
Tasks:
Use call() to borrow the showName method.
Use apply() to pass arguments using an array.
Use bind() and store the returned function in a variable, then execute it.
These small experiments help build intuition about how this it behaves.
Function and Caller
You can visualize the concept like this.
Object --------> Function
| |
| calls |
↓ |
person.greet() |
this → person
This shows that the caller decides what this it refers to.
Conclusion
Understanding this in JavaScript becomes much easier when you think about who is calling the function.
If a function is called normally, this usually refers to the global context. If it is called by an object, this refers to that object.
Methods like call(), apply(), and bind() give us control over the value of this. They allow functions to be reused across different objects, which improves flexibility and code reuse.



