Skip to main content

Command Palette

Search for a command to run...

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

Updated
6 min read
The Magic of `this`,` call()`, `apply()`, and `bind()` in JavaScript

JavaScript becomes much more powerful and flexible once you understand how this works. Many beginners find this confusing because its value is not fixed. It changes depending on how a function is called. Along with this, JavaScript provides three important methods — call(), apply(), and bind() — that allow developers to control what this refers to. In this article, we will understand these concepts in a very simple and practical way using basic examples.

What this Means in JavaScript

In simple terms, this means “who is calling the function.” It refers to the object that is currently executing a function. JavaScript decides the value of this at runtime, based on how the function is invoked. This behavior makes JavaScript flexible but also requires developers to clearly understand function calling patterns.

For example:

function show() {
  console.log(this);
}

show();

When this function is called in a browser, this refers to the global object, which is window. If the same code runs in strict mode, this will be undefined. The key idea here is that a normal function call does not have an owner object, so JavaScript assigns this differently depending on the environment.

this Inside Objects

When a function is called as a method of an object, this refers to that object. This is one of the most common and important use cases of this.

const user = {
  name: "Mahesh",
  greet: function () {
    console.log("Hello " + this.name);
  }
};

user.greet();

In this case, the user object is calling the greet function. Therefore, this refers to the user object, and the output becomes “Hello Mahesh.” This behavior allows objects to access their own properties using this.

It is important to understand that this does not depend on where the function is written. It depends on how the function is called. If the same function is assigned to another object, this will point to the new object.

What call() Does

The call() method allows you to manually set the value of this when calling a function. It is often used for function borrowing, where one object uses a function that belongs to another object.

The syntax of call() is:

functionName.call(thisValue, arg1, arg2);

Here is a simple example:

function greet(city) {
  console.log(this.name + " from " + city);
}

const person = {
  name: "Mahesh"
};

greet.call(person, "Bhubaneswar");

In this example, the greet function does not belong to the person object. However, by using call(), we force JavaScript to treat person as the caller. As a result, this.name becomes “Mahesh.” The function executes immediately after calling call().

This feature is useful when we want to reuse functions across different objects without rewriting the same logic multiple times.

What apply() Does

The apply() method works almost exactly like call(). The main difference is how arguments are passed. Instead of passing arguments individually, apply() expects them inside an array.

The syntax of apply() is:

functionName.apply(thisValue, [arg1, arg2]);

Consider the following example:

function greet(city, country) {
  console.log(this.name + " from " + city + ", " + country);
}

const person = {
  name: "Mahesh"
};

greet.apply(person, ["Bhubaneswar", "India"]);

Here, the function executes immediately just like call(). The only difference is that arguments are grouped in an array. This becomes especially useful when the number of arguments is dynamic or when data already exists in array form.

Developers often use apply() with built-in functions like Math.max() to find the maximum value in an array.

What bind() Does

The bind() method is different from both call() and apply(). Instead of executing the function immediately, it returns a new function with this permanently set to a specific value.

The syntax of bind() is:

const newFunction = functionName.bind(thisValue);

Here is an example:

function greet() {
  console.log("Hello " + this.name);
}

const person = {
  name: "Mahesh"
};

const greetUser = greet.bind(person);

greetUser();

In this case, bind() creates a new function called greetUser. This new function remembers that this should always refer to person. The function runs only when greetUser() is called.

This behavior is very useful in asynchronous programming, event listeners, callbacks, and situations where functions are passed around as values. Without bind(), the value of this might change unexpectedly.

Difference Between call(), apply(), and bind()

Understanding the differences between these three methods helps developers decide when to use each one. The most important difference is execution timing and argument format.

call() executes the function immediately and accepts arguments individually.

apply() also executes the function immediately but takes arguments as an array.

bind() does not execute the function immediately. Instead, it returns a new function with a fixed this value.

Another difference is use cases. call() is useful for quick function borrowing when arguments are known. apply() is helpful when arguments are stored in arrays or need to be passed dynamically. bind() is best suited for callbacks, event handling, and situations where we want to preserve the function context.

Real-World Understanding

You can think of a function as a tool that can be used by different objects. The value of this depends on who is currently using that tool. If an object uses the tool directly, this refers to that object. If we want another object to use the same tool, we can use call() or apply() to change the context instantly. If we want to prepare a version of the tool that always belongs to a specific object, we use bind().

This mental model makes it easier to understand how JavaScript manages execution context without diving into complex internal mechanisms.

When to Use Each Method

Use call() when you want to execute a function immediately with a specific object context and known arguments. Use apply() when arguments are available as an array or when working with dynamic data. Use bind() when you need to store a function for later use while ensuring that this does not change.

These methods become very important in frameworks like React, while working with event listeners, timers, promises, or any situation where functions are passed as callbacks.