Understanding JavaScript's 'this' Keyword: Context is Everything

ยท

3 min read

At the beginning, you should know that whenever you write JavaScript code, you are inside something called the window object. This window is a global object in the browser that contains all global methods and properties.

To see the window object, you can simply log it like this:

console.log(window); // Logs the window object
console.log(this);  // Also logs the window object (in the global scope)

๐Ÿ”น Determining the Value of this

The value of this depends on how and where a function is invoked.

1๏ธโƒฃ Global Context

If you try to log this globally (outside any function), it will always refer to the window object in the browser.

console.log(this); // Logs: window (in browsers)

2๏ธโƒฃ Regular Functions

There are two main types of functions:

  • Regular functions (defined with the function keyword)

  • Arrow functions (which do not use the function keyword)

Let's start with a regular function:

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

logThis();

Explanation:

  • The function logThis is invoked in the global scope.

  • Since it's a regular function, this refers to window in non-strict mode.

  • In strict mode, this would be undefined due to this substitution.

๐Ÿ“Œ this Substitution Rule

In strict mode ('use strict'), JavaScript prevents this from defaulting to window. Instead, this becomes undefined.

'use strict';
function logThis() {
    console.log(this);
}
logThis();
// Logs: undefined (in strict mode)

However, if we explicitly call logThis using window:

window.logThis();
  • It will log the window object in both strict and non-strict mode because the function is now being invoked as a method of window.

๐Ÿ”น this in Object Methods

If you have an object method (a function inside an object), this behaves differently:

const student = {
  grade: 100,
  message: function () {
    console.log(this);
    return `Your Grade is ${this.grade}`;
  },
};

console.log(student.message());

Explanation:

  • message is a regular function, so this inside it refers to the object that calls it (student).

  • Logging this inside message will return the student object.

  • this.grade correctly refers to student.grade.


๐Ÿ”น this in Arrow Functions

Arrow functions behave differently because they do not have their own this. Instead, they inherit this from the surrounding scope.

const student = {
  grade: 100,
  message: () => {
    console.log(this);
    return `Your Grade is ${this.grade}`;
  },
};

console.log(student.message());

Explanation:

  • message is an arrow function, meaning it does not create its own this.

  • It inherits this from its surrounding lexical scope, which in this case is the global scope (window).

  • Since window.grade is undefined, the function returns: "Your Grade is undefined".

โœ… Fix: Use a regular function instead, as shown in the previous object example.


๐Ÿ”น this in Nested Functions

If a regular function is inside another regular function, this resets to window (or undefined in strict mode):

const student = {
  grade: 100,
  message: function () {
    function innerFunction() {
      console.log(this);
      return `Your Grade is ${this.grade}`;
    }
    return innerFunction();
  },
};

console.log(student.message());

๐Ÿšจ Problem:

  • innerFunction is a regular function, so this defaults to window (or undefined in strict mode).

  • this.grade becomes undefined, resulting in: "Your Grade is undefined".

ย