Skip to main content

Command Palette

Search for a command to run...

Understanding the this Keyword in JavaScript

Demystifying JavaScript’s most notorious keyword by simply asking: "Who called the function?"

Published
5 min read
H
CS Graduate | Technical Writing | Software development | 20K+ impressions

If you spend enough time learning JavaScript, you will inevitably bump into the this keyword. And if you are like most developers, your first reaction will probably be confusion.

It is often considered one of the trickiest concepts in the language. Why? Because unlike variables that hold fixed values, the value of this is a shapeshifter. It changes depending on exactly where and how it is used.

However, you don't need to understand complex compiler theories or deep "execution context" internals to master it. You just need a solid mental model.

Here is your straightforward guide to understanding exactly what this represents in JavaScript.


What does this represent?

Instead of overcomplicating things, let’s use a simple, golden rule:

this simply refers to the "caller" of a function.

Imagine receiving a phone call. If the person on the other end says, "Hey, it's me!", the word "me" means something entirely different depending on who dialed your number.

In JavaScript, this is just like the word "me". It is a dynamic reference to the object that invoked (or called) the function. If you want to know what this is at any given moment, just look to the left of the dot when the function is called.

Let's look at how this plays out in different scenarios.


1. this in the Global Context

Before we even look at functions, what happens if we just log this right out in the open, at the top level of our code?

console.log(this);

When you are in the global scope (outside of any specific function or object), this defaults to the Global Object.

  • If you are running this in a browser, it will output the window object.

  • If you are running this in Node.js, it will output the global object.

It is essentially the base environment where all your JavaScript code is currently living.


2. this Inside Objects

This is where this becomes incredibly useful. When a function is stored inside an object, it is known as a method.

When you call a method, this points directly to the object that owns the method.

const user = {
  name: "Alice",
  age: 25,
  introduce: function() {
    // "this" refers to the 'user' object
    console.log(`Hi, I am ${this.name}.`);
  }
};

user.introduce(); 
// Output: Hi, I am Alice.

How do we know what this is? Look at how the function is called: user.introduce(). Who is calling the function? The user object. Therefore, inside the function, this.name translates perfectly to user.name.


3. this Inside Regular Functions

What happens if a function is not inside an object, and we just call it directly?

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

sayHello(); 

Let's apply our rule: Who is calling the function?

When you call sayHello() like this, there is no object to the left of a dot. It is just floating in the global space. Because of this, the global object (the browser's window) takes responsibility for the call.

So, in a normal function, this defaults to the global window object.

(Note: Modern JavaScript developers often use Strict Mode by writing 'use strict'; at the top of their files. In Strict Mode, JavaScript stops defaulting to the global window object. Instead, this will simply be undefined. This is actually a good thing, as it prevents accidental bugs!)


How Calling Context Changes this

The most important takeaway is that this is not assigned when you write the function; it is assigned when you call the function.

This means the exact same function can have a completely different this value if you call it differently. Let’s look at a classic "gotcha" scenario that catches many developers off guard: losing the context.

const car = {
  brand: "Toyota",
  startEngine: function() {
    console.log(`Starting the ${this.brand}...`);
  }
};

// Scenario A: Calling it as a method
car.startEngine(); 
// Output: Starting the Toyota...

// Scenario B: Assigning it to a new variable
const startMyCar = car.startEngine;

// Calling the new variable
startMyCar(); 
// Output: Starting the undefined...

Wait, what just happened in Scenario B?

When we created startMyCar, we extracted the function out of the car object. When we finally called startMyCar(), we called it as a regular, standalone function. There is no car. in front of it anymore.

Because it was called globally, this defaulted to the global window object. The window object does not have a brand property, so this.brand evaluated to undefined.

The function hasn't changed. The caller changed.


Taking Control of this

Understanding how this behaves naturally is step one. But what happens when you want to fix the broken context in Scenario B? What if you want to manually force this to point to a specific object, regardless of how the function is called?

JavaScript gives us three powerful, built-in methods to manually control our calling context: call(), apply(), and bind().

If you are ready to take the next step and learn how to manipulate this at will, check out my comprehensive follow-up blog:
👉 The Magic of this, call(), apply(), and bind() in JavaScript

Summary

Whenever you find yourself confused by what this is doing in your code, stop and ask yourself: "Who is calling the function?"

  1. Global scope: this is the global window object.

  2. Inside an object method (obj.method()): this is the object before the dot.

  3. Inside a standalone function (func()): this is the global window object (or undefined in strict mode).

Keep that simple mental model in mind, and the this keyword will quickly become one of your favorite tools in JavaScript!

Web Development Cohort

Part 28 of 50

These are the assignments or knowledge dumps I decide to write for the "Chai aur Code's web Dev Cohort 2026"

Up next

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

Learn about this keyword and learn how to control function context like a pro.