DEV Community

Cover image for Understand JavaScript 'this' keyword in 5 easy steps
Anwar Sadat Ayub
Anwar Sadat Ayub

Posted on

Understand JavaScript 'this' keyword in 5 easy steps

Javascript is a very popular programming language. It is a go-to programming language for most beginners. But going deeper, you realize that it has some weird concepts which can be frustrating for most beginners. I have had my share and that’s why I have put this article together. In this article, we will break down ‘this’ keyword in Javascript in 5 easy steps. At the end of this article, you should be conversant with ‘this’ object and conveniently use it in your code.

Before we proceed, I would make this clear first. I would assume that you are familiar with Javascript Functions and at least basic knowledge of OOP in Javascript. You can read JavaScript Functions Made Easy: Streamlining Code for Beginners! on functions and Classes in Javascript on Javascript Classes.
Also, you will need to follow along with the coding part. Just reading through the article will not help you much.

Introduction to ‘this’ keyword

‘this’ is used for a person, object, or thing to show which one is referred to by way of emphasis. For example, you could say “This is my laptop, yours is over there”. In this sentence, you referred to your laptop using ‘this’ to emphasize which of the two laptop is yours. Similarly, you use the ‘this’ keyword to refer to a specific, or even better, the current object in Javascript. The object that is referred to will depend on the context or ‘environment’ where your code runs. Whatever the context, you would use ‘this’ to refer to that context.

Take note that the value of ‘this’ object depends on how a function is invoked and not how a function is defined. Understanding the code execution context is very crucial to knowing what to expect when you use the ‘this’ keyword.

Javascript Execution Context

Simply put, the execution context is the environment in which code is executed. Each context comes with its settings such as the variable scope, the ‘this’ keyword, and the rules that determine how the code behaves. We will not discuss the execution context in detail. Just think of it as the wrapper that manages your code. However, I will explain some concepts in which the ‘this’ keyword can be invoked i.e. the regular function context, arrow function context, and class context.

Before I go into explaining these 3 contexts, let's take a look at the Global Context. The global context is represented by the ‘window’ object. This ‘window’ object is automatically created by the browser when a web page is loaded. It represents the browser window or the global environment in which the code runs within the page. Imagine the ‘window’ object as your external .js file or the inline code between the <script></script> except code that is in blocks or functions.

Let’s consider this line of code in the global context of a browser as illustrated below;

//Global execution context
console.log(window === window); //true in a web browser
Enter fullscreen mode Exit fullscreen mode

We compare the ‘window’ object to itself which obviously will be true.

Now let's check if ‘this’ is the same as the ‘window’ object’;

//Global execution context
console.log(this === window); //true in a web browser
Enter fullscreen mode Exit fullscreen mode

We get true as well. Therefore we can refer to the ‘window’ object with ‘this’ and get all the properties and methods that the ‘window’ object holds.

Let's take another example. Do you know the alert() function? It’s a method of the window object. Run the following code;

window.alert('hello');
Enter fullscreen mode Exit fullscreen mode

which is equivalent to

this.alert('hello');
Enter fullscreen mode Exit fullscreen mode

You can also create your methods and properties in the ‘window’ object. Create variables or functions without using the variable declaration keyword to make global variables and methods.

However, when you are in the ‘strict mode’, ‘this’ will result in ‘undefined’ if not bound explicitly. This is used to detect potential bugs and encourage developers to be more explicit about their code’s behavior.

Understanding ‘this’ in regular function

A regular function is a function that is defined using the function keyword followed by the function name, list of parameters separated by commas and enclosed in parenthesis with the code that defines the function enclosed inside curly braces as shown below;

function name(parameter){
  //Your function's code goes here
}
Enter fullscreen mode Exit fullscreen mode

Each function creates its own scope and context. This means it encapsulates variables within its scope and defines its own context through the ‘this’ keyword. The value of the ‘this’ keyword depends on how the function is invoked.

  • When a regular function is invoked in the global context, ‘this’ refers to the global object which is the window object.
function greet(){
    console.log(this);
}

greet(); // window {...}
Enter fullscreen mode Exit fullscreen mode
  • If the function is invoked using the new constructor keyword, a new empty object is created and ‘this’ will refer to that empty object;
function Greet(){
    console.log(this);
}

let Hello = new Greet();

Hello //greet{}

Enter fullscreen mode Exit fullscreen mode

Now let's modify our code;

function Greet(){
    let message = 'Hello there';

    console.log(this);
}

let Hello = new Greet();

Hello // Greet{}
Enter fullscreen mode Exit fullscreen mode

We are not getting the message variable as a property to the newly created Greet{} object because the message variable was not declared as a property of ‘this’ object.

Let’s add the message variable to the ‘this’ object;

function Greet(){
    this.message = 'Hello there';

    console.log(this);
}

let Hello = new Greet();

Hello // Greet {message: 'Hello there'}
Enter fullscreen mode Exit fullscreen mode

We can also use the bind() method to set the context for our

function;
//create the function
function person(){
    console.log(this.name);
}

// use bind to set context
var obj = {
    name: 'John Smith',
}
var newPerson = person.bind(obj)

// bind() method returns a new function with the context set to obj

newPerson(); // John Smith
Enter fullscreen mode Exit fullscreen mode

Hence with regular functions, you can either use the new constructor keyword or the bind method to set the context of the function.

Arrow function and ‘this’ object

Arrow functions in JavaScript do not have their own ‘this’ context. Instead, they inherit the 'this’ value from the enclosing lexical or outer context. This behavior can sometimes be an advantage, especially in scenarios where you want to maintain the context of ‘this’ within nested functions.

Consider the code below;
const obj = {
    name: "John Smith",
    greet: function() {
      console.log(`Hello, my name is ${this.name}`);
    },
    greetArrow: () => {
      console.log(`Hello, my name is ${this.name}`); // 'this' here refers to the outer context
    }
  };

  obj.greet(); // Output: Hello, my name is John
  obj.greetArrow(); // Output: Hello, my name is undefined
Enter fullscreen mode Exit fullscreen mode

The name value is undefined because there is no name property for the global context. To correct this, we add the name to the outer scope;

this.name = 'John Doe' //name property in the outer context

const obj = {
    name: "John Smith",
    greet: function() {
      console.log(`Hello, my name is ${this.name}`);
    },
    greetArrow: () => {
      console.log(`Hello, my name is ${this.name}`); // 'this' here refers to the outer context
    }
  };

  obj.greet(); // Output: Hello, my name is John
  obj.greetArrow(); // Output: Hello, my name is John Doe
Enter fullscreen mode Exit fullscreen mode

However, using ‘this’ in the arrow function can be a pitfall if you rely on dynamic ‘this’ binding, especially in event handlers or prototype methods.

‘this’ in Class context

Classes are blueprints or templates for creating objects. you specify the properties (data) and methods (behavior) that each object created from the class will have. If you need a new object, you just create it using the new constructor keyword.

The ‘this’ keyword behaves differently in class contexts such as;

  1. When used inside the constructor method, ‘this’ refers to the newly created instance of the class. It allows you to set properties on the object during initialization.
class Person{

    constructor(name){
        this.name = name;
    }

}

let sarah = new Person('Sarah');

console.log(sarah.name) // Sarah
Enter fullscreen mode Exit fullscreen mode
  1. Functions in a class are called methods. When methods are invoked, the ‘this’ references the new instance of the class on which the method is called. It allows methods to access and manipulate the properties of the object.
class Person{

    constructor(name){
        this.name = name;
    }

    greet(){
        return `Hi, they call me ${this.name}`;
    }

}

let sarah = new Person('Sarah');

console.log(sarah.greet()) // Hi, they call me Sarah
Enter fullscreen mode Exit fullscreen mode
  1. When a static method is called, it is invoked directly on the class itself, rather than on an instance of the class. Therefore, ‘this’ within a static method does not refer to an instance of the class; instead, it refers to the class itself.
class Person{

    static introduce(){
        return `Welcome to Person class`;
    }

}

console.log(Person.introduce());
Enter fullscreen mode Exit fullscreen mode

Conclusion

In summary, ‘this’ allows you to dynamically refer to different objects depending on how functions are called or where they are defined, providing flexibility and context-aware behaviour in your code.

Top comments (0)