Munsif.
AboutExperienceProjectsAchievementsBlogsContact
HomeAboutExperienceProjectsAchievementsBlogsContact
Munsif.

Frontend Developer crafting scalable web applications with modern technologies and clean code practices.

Quick Links

  • About
  • Experience
  • Projects
  • Achievements
  • Blogs
  • Contact

Connect

© 2026 Shaik Munsif. All rights reserved.

Built with Next.js & Tailwind

0%
Welcome back!Continue where you left off
Back to Blogs
JavaScript

Demystifying the JavaScript 'this' Keyword: A Visual Guide

Never be confused by 'this' again. Master implicit binding, explicit binding (call/apply/bind), and arrow functions with clear, visual examples.

Jan 27, 202618 min read
JavaScriptThis KeywordObject OrientedInterview PrepCore Concepts
JavaScript MasteryPart 6 of 11
  • 1. JavaScript Type Coercion Mastery: A Senior Engineer's Guide to the Chaos
  • 2. JavaScript Runtime Deep Dive: Event Loop, Call Stack & Async Execution
  • 3. Mastering JavaScript Callbacks: From Sync to Async & The Event Loop
  • 4. JavaScript Closures Deep Dive: Mastering Lexical Scope & Memory
  • 5. JavaScript Object Prototyping Mastery: A Visual Guide to Inheritance
  • 6. Demystifying the JavaScript 'this' Keyword: A Visual Guide
  • 7. JavaScript Promises & Promise Chaining Mastery: From Callbacks to Async Flow
  • 8. JavaScript Array Methods Mastery: Complete Guide from map() to reduce()
  • 9. JavaScript Map & Set Mastery: Complete Guide to Modern Data Structures
  • 10. JavaScript String Methods Mastery: Complete Guide from slice() to replaceAll()
  • 11. JavaScript Regular Expressions Mastery: Real-World Patterns & Validation

Introduction

Ask a room of developers what this refers to in JavaScript, and you'll get five different answers and a lot of nervous sweating.

The this keyword is widely misunderstood because it doesn't behave like variables in other languages. In most cases, this is not determined by where a function is written, but by where it is called.

To master this, you just need to learn the 4 rules of binding and one special exception.


The Analogy: The Magic Pronoun

Think of this like the word "My" in English.

  • If I say "My shirt", I mean Munsif's shirt.
  • If you say "My shirt", you mean Your shirt.
  • The word "My" stays the same, but the owner changes depending on who is speaking.

In JavaScript, this is that word. It refers to the current owner of the code being executed.


Rule 1: Default Binding (Global)

If you call a function normally, without any context, this refers to the Global Object.

  • In a browser script tag, that's window.
  • In Node.js, that's global.
  • Note: In ES6 Modules (like React/Next.js) or "Strict Mode", default binding is disabled, so this will be undefined.
javascript
function sayName() {
    console.log(this.name);
}

var name = 'Global Context';
sayName(); // Output: "Global Context"

Wait! If you are using "use strict", default binding is ignoring. this will be undefined.

javascript
"use strict";
function sayName() {
    console.log(this); // undefined
}

Rule 2: Implicit Binding (Object)

This is the most common scenario. If a function is called as a method of an object (e.g., obj.method()), this refers to that object.

javascript
const user = {
    name: 'Alice',
    greet: function() {
        console.log(`Hello, I am ${this.name}`);
    }
};

user.greet(); // "Hello, I am Alice"

Common Pitfall: Losing this If you separate the function from the object, you lose the binding.

javascript
const greetInstance = user.greet;
greetInstance(); // Rule 1 takes over! "Hello, I am undefined"

This happens frequently when passing methods as callbacks (e.g., in React or Event Listeners).

Real Life Scenario 1: Borrowing Methods (Code Reusability)

Imagine you have two different objects (gamers), but you don't want to write the same "Score" function twice. You can write it once and share it!

javascript
const player1 = { name: 'Mario', score: 0 };
const player2 = { name: 'Luigi', score: 0 };

function addScore(points) {
    this.score += points;
    console.log(`${this.name} now has ${this.score} points`);
}

// "Borrow" the function for Mario
addScore.call(player1, 100); // "Mario now has 100 points"

// "Borrow" the function for Luigi
addScore.call(player2, 50);  // "Luigi now has 50 points"

This is the power of this. We wrote addScore once, but it can work for any player. We just have to tell it who "this" is using .call().


Rule 3: Explicit Binding (call, apply, bind)

We can force a function to use a specific object as this using three built-in methods.

.call() and .apply()

These invoke the function immediately.

javascript
function introduce(lang1, lang2) {
    console.log(`I am ${this.name} and I code in ${lang1} and ${lang2}`);
}

const me = { name: 'Munsif' };

// arguments separated by comma
introduce.call(me, 'JS', 'Python'); 

// arguments in an array
introduce.apply(me, ['JS', 'Python']); 

.bind()

This returns a new function that is permanently locked to the specified context. It does not invoke it immediately.

javascript
const boundIntroduce = introduce.bind(me);
boundIntroduce('JS', 'Python'); // Works beautifully

bind is the cure for the "Losing this" problem mentioned in Rule 2.


Rule 4: New Binding (Constructor)

When you use the new keyword, a brand new object is created, and this is bound to that new object.

javascript
function User(name) {
    // this = {} (created implicitly)
    this.name = name;
    // return this (implicit)
}

const bob = new User('Bob');
console.log(bob.name); // "Bob"

This rule has the highest precedence.


The Exception: Arrow Functions

Arrow functions (=>) were introduced in ES6 and they ignore all the rules above.

Arrow functions do not have their own this. Instead, they inherit this from the surrounding scope (Lexical Scoping).

javascript
const obj = {
    name: 'Arrow',
    regular: function() {
        console.log(this.name);
    },
    arrow: () => {
        console.log(this.name);
    }
};

obj.regular(); // "Arrow" (Rule 2)
obj.arrow();   // undefined (Inherits Global Scope)

Why is this useful?

It's perfect for callbacks inside methods!

javascript
const timer = {
    seconds: 0,
    start() {
        setInterval(() => {
            this.seconds++; // 'this' correctly refers to timer object
            console.log(this.seconds);
        }, 1000);
    }
};

timer.start();

If we used a regular function inside setInterval, this would default to window (Rule 1), and it would break.


Real Life Scenario 2: The Button Click

When you click a button on a webpage, the browser automatically binds this to the button element itself.

javascript
const button = document.querySelector('button');

button.addEventListener('click', function() {
    // 'this' is the HTML element that was clicked
    console.log("You clicked:", this); 
    
    // We can easily change its text
    this.innerText = "Clicked!"; 
});

Common Mistake: Using an Arrow Function here.

javascript
button.addEventListener('click', () => {
    // Arrow functions don't have their own 'this'
    // It will look at the outer scope (Window) and fail
    this.innerText = "Clicked!"; // Error!
});

Rule of Thumb: dealing with HTML elements? Use a regular function.


Summary (Cheat Sheet)

To figure out what this is, ask these questions in order:

  1. Is it called with new? -> It's the new object.
  2. Is it called with call, apply, or bind? -> It's the specified object.
  3. Is it called as obj.method()? -> It's obj.
  4. Is it an Arrow Function? -> It's the same as the outer scope.
  5. Otherwise? -> It's global (window) or undefined (strict mode).

🧠 Test Your Knowledge

Now that you've learned the concepts, let's see if you can apply them! Take this quick quiz to test your understanding.

PreviousJavaScript Object Prototyping Mastery: A Visual Guide to InheritanceNextJavaScript Promises & Promise Chaining Mastery: From Callbacks to Async Flow

Written by

Shaik Munsif

Read more articles

Found this helpful? Share it with your network!

On this page

0/13
Question 1 of 18Easy
Score: 0/0

What is the output?

javascript
console.log(this === window);