Skip to main content

Command Palette

Search for a command to run...

Mastering this in JavaScript

Updated
7 min read
Mastering  this in JavaScript

In previous blog Arrow function we have studied about arrow function and in this blog we are gonna learn about this keyword and apply , bind and call method.

One day, an uncle in my colony asked me to go to the grocery shop and bring a toothpaste. He didn’t give me any money and told me, “Just tell the shopkeeper to write it in the account.”

So I went to the shop and asked the shopkeeper for a toothpaste. After giving it to me, he asked, “Whose account should I write it in?”

At that moment I said my uncle’s name. Suddenly I realized something interesting — this situation is very similar to the concept of this in JavaScript.

In JavaScript, this refers to the object that called the function. Just like the shopkeeper needed to know who sent me so he could write the toothpaste in the correct account, JavaScript also determines who called the function to decide what this should refer to.

this means who called you or who sent you

Let study more about this

when we console.log this inside regular function in browser it points to window object and in node js environment it points to global object and when we use "use strict" it shows undefined.

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

Browser:

Node:

this inside Objects

Let’s understand this using the same uncle analogy.

const uncle = {
  name: "Mr. Sharma",
  buyToothpaste: function() {
    console.log(`Writing toothpaste in ${this.name}'s account.`);
  }
};

uncle.buyToothpaste();
// Output: Writing toothpaste in Mr. Sharma's account.

Inside an object, the value of this depends on how the function is called.

In the example above, we are calling the function using:

uncle.buyToothpaste()

So the object uncle is calling the function, which means inside the regular function:

this → uncle

That’s why this.name becomes "Mr. Sharma".

This matches our analogy: the shopkeeper writes the toothpaste in the account of the person who sent you.


Arrow Functions Work Differently

Arrow functions do not determine this based on who calls them.

Instead, they inherit this from their lexical (outer) scope.

const uncle = {
  name: "Mr. Sharma",
  buyToothpaste: () => {
    console.log(`Writing toothpaste in ${this.name}'s account.`);
  }
};

uncle.buyToothpaste();
// Output: Writing toothpaste in undefined's account.

Here, the arrow function does not bind this to the uncle object.

Instead, it takes this from the outer scope (global scope). Since the global object does not have name = "Mr. Sharma", the result becomes:

undefined

A Tricky Example That Shows the Importance of Arrow Functions

Let’s look at another example that shows why arrow functions can sometimes be very useful.

const uncle = {
  name: "Mr. Sharma",
  brand: "colgate",
  buyToothpaste: function() {
    function brandName() {
      console.log(`Writing \({this.brand} toothpaste in \){this.name}'s account.`);
    }

    brandName();
  }
};

uncle.buyToothpaste();

Output

Writing undefined toothpaste in undefined's account.

Why does this happen?

Inside buyToothpaste, we created another regular function:

function brandName() { ... }

And we called it like this:

brandName();

This is a normal function call, not an object method call.

Since this in a regular function depends on how the function is called, and no object is calling brandName, JavaScript sets:

this → global object (or undefined in strict mode)

Because the global object does not have brand or name, the result becomes:

undefined

Fixing It Using Arrow Function

Now let's rewrite the inner function using an arrow function.

const uncle = {
  name: "Mr. Sharma",
  brand: "colgate",
  buyToothpaste: function() {
    const brandName = () => {
      console.log(`Writing \({this.brand} toothpaste in \){this.name}'s account.`);
    };

    brandName();
  }
};

uncle.buyToothpaste();

Output

Writing colgate toothpaste in Mr. Sharma's account.

Why Arrow Function Works Here

Arrow functions do not create their own this.

Instead, they inherit this from their surrounding scope.

Here the surrounding scope is buyToothpaste, where:

this → uncle

So the arrow function uses the same this.


Key Takeaway

Regular function → this depends on how the function is called

Arrow function → this comes from the surrounding (lexical) scope

This is why arrow functions are often used inside object methods when we need access to the parent object's this.

Now That We Understand this, Let's Explore call, apply, and bind

Now that we are comfortable with how this works, let's explore three important methods that allow us to manually control the value of this:

  • call

  • apply

  • bind


The Problem

Suppose we have an object representing our uncle:

const uncle = {
  name: "Mr. Sharma",
};

And a function that writes the toothpaste purchase in the account.

function buyToothpaste(brand, size) {
  console.log(`Writing \({brand} \){size} size toothpaste in ${this.name}'s account.`);
}

buyToothpaste("colgate", "small");

Output

Writing colgate small size toothpaste in undefined's account.

Why Does This Happen?

Here the function is called like this:

buyToothpaste()

This is a normal function call, not a method call.

Because of that:

this → global object

The global object does not have a name property, so this.name becomes:

undefined

Fixing It Using call

We can override the value of this using the call method.

const uncle = {
  name: "Mr. Sharma",
};

function buyToothpaste(brand, size) {
  console.log(`Writing \({brand} \){size} size toothpaste in ${this.name}'s account.`);
}

buyToothpaste.call(uncle, "colgate", "small");

Output

Writing colgate small size toothpaste in Mr. Sharma's account.

Here we explicitly tell JavaScript:

Use uncle as this

Using apply

apply works almost the same as call.

The only difference is how arguments are passed.

With call:

Arguments are passed separately

With apply:

Arguments are passed inside an array

Example

buyToothpaste.apply(uncle, ["colgate", "small"]);

Output

Writing colgate small size toothpaste in Mr. Sharma's account.

Using bind

bind works slightly differently.

Instead of executing the function immediately, bind returns a new function with this permanently set.

Example

const uncle = {
  name: "Mr. Sharma",
};

function buyToothpaste(brand, size) {
  console.log(`Writing \({brand} \){size} size toothpaste in ${this.name}'s account.`);
}

const buyForUncle = buyToothpaste.bind(uncle);

buyForUncle("colgate", "small");

Output

Writing colgate small size toothpaste in Mr. Sharma's account.

Here bind creates a new function where this will always be uncle.


Quick Summary

Method Executes Immediately Arguments
call() Yes Passed individually
apply() Yes Passed as an array
bind() No Returns a new function

Conclusion

The this keyword in JavaScript helps determine which object's data a function should use. A simple way to think about it is: “Who called the function?” — just like the shopkeeper in our story needed to know whose account to write the toothpaste in.

We saw that in regular functions, the value of this depends on how the function is called, while arrow functions inherit this from their surrounding scope. We also learned how methods like call, apply, and bind allow us to manually control or override the value of this when needed.