Who Is Calling the Function? Understanding this, call(), apply(), and bind() in JavaScript

Understanding this, call(), apply(), and bind() in JavaScript
When developers first encounter this in JavaScript, it can feel confusing. But if you simplify the idea, it becomes much easier to understand. A helpful way to think about this is: “Who is calling the function?” In JavaScript, the value of this usually depends on the object that is calling the function.
What this Means in JavaScript
In simple terms, this refers to the current context of execution, or more practically, the object that is calling the function. If a function is called by an object, this points to that object. If it’s called without an object, the value of this changes depending on the environment.
Example:
function show() {
console.log(this);
}
show();
In this case, the function is not called by any object. So this refers to the global context (in browsers it would usually be the window object).
The real usefulness of this becomes clearer when working with objects.
this Inside Objects
When a function is defined as a method inside an object, this refers to that object.
Example:
let person = {
name: "Satyam",
age: 21,
greet: function() {
console.log("Hello, my name is " + this.name);
}
};
person.greet();
Output:
Hello, my name is Satyam
Here the function greet() is called by the person object, so this.name refers to person.name.
You can visualize it like this:
person object
↓
calls greet()
↓
this → person
So whenever the function runs, this refers to the object that invoked it.
Borrowing Functions Between Objects
Sometimes you might want one object to use a method that belongs to another object. JavaScript provides special methods for this purpose: call(), apply(), and bind().
These methods allow you to control what this refers to.
Using call()
The call() method allows you to call a function and explicitly specify what this should refer to.
Example:
let person1 = {
name: "Satyam"
};
let person2 = {
name: "Rahul"
};
function greet() {
console.log("Hello " + this.name);
}
greet.call(person1);
greet.call(person2);
Output:
Hello Satyam
Hello Rahul
Here we are using the same function but changing the context using call().
You can also pass arguments after the first parameter.
function introduce(city) {
console.log(this.name + " lives in " + city);
}
introduce.call(person1, "Delhi");
Using apply()
The apply() method works very similarly to call(). The main difference is how arguments are passed.
With call(), arguments are passed individually.
With apply(), arguments are passed as an array.
Example:
function introduce(city, country) {
console.log(this.name + " lives in " + city + ", " + country);
}
introduce.apply(person1, ["Delhi", "India"]);
The behavior is the same; the only difference is the argument format.
Using bind()
The bind() method is slightly different. Instead of immediately calling the function, bind() returns a new function with this permanently set.
Example:
let person = {
name: "Satyam"
};
function greet() {
console.log("Hello " + this.name);
}
let greetPerson = greet.bind(person);
greetPerson();
Here bind() creates a new function where this always refers to person.
This is useful when passing functions around, such as in event handlers or callbacks.
Difference Between call, apply, and bind
| Method | What it does | Arguments |
|---|---|---|
| call() | Calls the function immediately | Passed individually |
| apply() | Calls the function immediately | Passed as an array |
| bind() | Returns a new function | Arguments can be preset |
Another way to think about it:
call → run function now
apply → run function now (arguments as array)
bind → create a new function to run later
Visual Idea of this
You can imagine this as the connection between a function and its caller.
Object
↓
calls function()
↓
this refers to that object
So this always depends on how the function is called.
Final Thought
Understanding this is an important step toward mastering JavaScript. While it may seem tricky at first, the core idea is simple: this usually refers to the object that calls the function. Methods like call(), apply(), and bind() give developers more control over that relationship, allowing functions to be reused across different objects. Once you become comfortable with these concepts, many advanced JavaScript patterns will start making much more sense.
