Skip to main content

Command Palette

Search for a command to run...

Understanding the this Keyword in JavaScript

Updated
9 min read
Understanding the this Keyword in JavaScript

If there is one JavaScript concept that confuses almost every beginner at some point, it is this.

At first, it looks simple. It is just a keyword, so you naturally expect it to always point to one clear thing. But then you see the same function behave differently in different situations, and this starts feeling unpredictable.

The truth is, this is not random. It follows a rule.

The core idea

this usually refers to the object that is calling the function.

That one idea clears up most of the confusion.

In this article, we will understand what this represents, how it behaves in the global context, how it works inside objects and functions, and why the calling context matters so much.


What this represents

In JavaScript, this is a special keyword that refers to an object while code is running.

But unlike a normal variable, this does not always point to the same thing. Its value depends on how a function is called.

That is the key point.

A lot of beginners try to understand this by asking where the function is written. That helps a little, but it does not explain the full behavior. The better question is:

Who is calling this function right now?

That caller usually decides the value of this.

Example: method call

const user = {
  name: "Niharika",
  greet() {
    console.log(this.name);
  }
};

user.greet();

Output:

Niharika

Why does this work? Because greet() is being called by user. So inside that function, this refers to user.

Mental model

flowchart LR
  A["Function runs"] --> B["Ask: Who called me?"]
  B --> C["If an object called it"]
  C --> D["`this` becomes that object"]
  B --> E["If no object called it directly"]
  E --> F["`this` follows regular function rules"]

This is the mental model you should carry through the rest of the article.


this in the global context

When you use this outside any function or object, you are in the global context.

In a browser environment, the global object is window. So if you write this in the browser console:

console.log(this);

You will usually see the window object.

That also means:

console.log(this === window); // true

So in the browser’s global scope, this usually points to window.

This is often the first version of this that beginners see, which is why many assume this always means window. But that is only true in the global browser context. Once functions and objects come into the picture, the value of this can change.

For learning purposes, this is enough to remember:

  • In the browser global scope, this usually refers to window.
Context console.log(this) in browser
Global scope Browser global object → window

So global context is one case, not the complete definition of this.


this inside objects

This is one of the most common and useful places where this appears.

When a function is called as a method of an object, this usually refers to that object.

const person = {
  name: "Rahul",
  age: 22,
  introduce() {
    console.log(`Hi, I am \({this.name} and I am \){this.age} years old.`);
  }
};

person.introduce();

Output:

Hi, I am Rahul and I am 22 years old.

Here, this.name means person.name, and this.age means person.age.

Why? Because person is the one calling introduce().

This is exactly why this is useful. It allows an object to access its own properties without hardcoding its name again and again.

You could write:

const person = {
  name: "Rahul",
  age: 22,
  introduce() {
    console.log(`Hi, I am \({person.name} and I am \){person.age} years old.`);
  }
};

This works, but it is not ideal. If the object name changes later, you would have to update the method too. Using this makes the code cleaner and easier to maintain.

Caller diagram

Call Caller Inside the method
person.introduce() person thisperson

Rule of thumb: whenever you see an object method, think:

The object before the dot is usually the value of this.


this inside functions

Now let’s look at regular functions.

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

showThis();

If you run this in a browser in non-strict mode, this usually refers to the global object, which is window.

That can feel strange at first, especially if you expect this to refer to the function itself. But this does not refer to the function — it refers to the calling context.

In a regular function call like showThis(), there is no object before the dot calling it. So in many browser cases, JavaScript falls back to the global object.

That is why this inside a normal function behaves differently from this inside an object method.

The function itself did not change. The way it was called decides the value of this.

flowchart TD
  A["Regular function call"] --> B["`showThis()`"]
  B --> C["No object before the dot"]
  C --> D["`this` depends on runtime context"]
  D --> E["Browser non-strict mode: often `window`"]

How calling context changes this

This is the most important part of the topic.

The value of this can change even when the function stays exactly the same.

const car = {
  brand: "Toyota",
  showBrand() {
    console.log(this.brand);
  }
};

car.showBrand();

Output:

Toyota

This is straightforward. car is calling showBrand(), so this refers to car.

Now look at this:

const car = {
  brand: "Toyota",
  showBrand() {
    console.log(this.brand);
  }
};

const display = car.showBrand;
display();

Now the function is no longer being called by car.

It is being called as a regular function through display().

So this changes.

The function did not change. The code inside it did not change. The only thing that changed was the caller.

That is why the output is no longer "Toyota".

This is exactly where this starts making sense for most learners. It is not about where the function was originally written. It is about how it is being called right now.

flowchart TD
  A["`car.showBrand()`"] --> B["Caller is `car`"]
  B --> C["`this = car`"]
  C --> D["Output: `Toyota`"]

  E["`const display = car.showBrand`"] --> F["`display()`"]
  F --> G["`car` is no longer the caller"]
  G --> H["`this` changes"]
  H --> I["Output is no longer `Toyota`"]

A very practical way to think about it:

this answers the question: “Who called me?”

If car called the function, this is car. If no object called it directly, this follows the rules of a regular function call.


call(), apply(), and bind()

JavaScript also gives you ways to control the value of this manually. This is useful when you want a function to run with a specific object as its context.

call()

function greet() {
  console.log(`Hello, ${this.name}`);
}

const user = { name: "Sara" };

greet.call(user);

Output:

Hello, Sara

call() invokes the function immediately and sets this to user.

apply()

apply() works like call(), but it passes arguments as an array (or array-like).

function introduce(city) {
  console.log(`\({this.name} lives in \){city}`);
}

const user = { name: "Imran" };

introduce.apply(user, ["Delhi"]);

Output:

Imran lives in Delhi

bind()

bind() is different: it does not run the function right away. It returns a new function with this bound to the object you provide.

function greet() {
  console.log(`Hi, ${this.name}`);
}

const user = { name: "Meera" };

const boundGreet = greet.bind(user);
boundGreet();

Output:

Hi, Meera
Method When it runs this behavior
call() Immediately Set for that invocation
apply() Immediately Set for that invocation (args as array)
bind() Returns new function New function keeps the bound this

So if you want to control this yourself, these methods are the tools to use.


A common beginner mistake

One common misunderstanding is thinking that this always refers to the object where the function was written. That is not always true.

const person = {
  name: "Riya",
  sayName() {
    console.log(this.name);
  }
};

const anotherFunction = person.sayName;
anotherFunction();

At first glance, you may think this should still print "Riya" because the function came from person.

But it does not work that way.

Once the function is copied into anotherFunction and called on its own, the original object is no longer the caller. So this is no longer person.

Where it was defined Actual caller What decides this?
Inside person anotherFunction() at runtime Runtime caller

Understanding the caller matters more than understanding where the function was defined — that distinction prevents a lot of confusion.


A simple rule to remember

If you want one short rule that helps in most situations:

this depends on the caller of the function.

You can summarize it like this:

  • In the global scope, this usually refers to the global object.

  • In an object method, this usually refers to the object calling the method.

  • In a regular function call, this depends on the runtime context (and strict mode).

  • With call(), apply(), and bind(), you can set this yourself.

Once you start looking at the caller instead of only the function definition, this becomes much easier to predict.


Conclusion

The this keyword feels difficult in the beginning because its value changes from one situation to another. But the idea behind it is simple once you stop treating it like a fixed variable.

this is mostly about how a function is called.

  • If an object calls a method, this usually points to that object.

  • If a function is called on its own, this behaves according to the rules of that call (global / undefined in strict mode, etc.).

  • If needed, JavaScript gives you call(), apply(), and bind() to control it directly.

So whenever you feel confused about this, pause and ask one question:

Who is calling this function?

Most of the time, that question gives you the answer.