The this keyword in Javascript

The this keyword in Javascript

The this keyword has got to be one of the most misunderstood concepts in Javascript, especially to beginners. I remember being frustrated by it on more than one occasion. Some might even say that it is one of the most challenging concepts to understand in Javascript. In order to read and write good Javascript code, you must understand the this keyword. In this tutorial, I will endeavor to break it down and show you how the this keyword works and that there is no reason to be scared of it.

What is the this keyword?

The this keyword is a special variable automatically created for every function by Javascript, and it will point to or take the value of the "owner" of the function that is calling it. The this keyword is dynamic, and its value is assigned or known only when the function is called and depends on how the function is called. There are four (4) ways to call a function in Javascript, and the value of the this keyword changes in each way.

1) As a Method:

For a function to be called as a method, it must be defined as a property on an object or as a function that is attached to an object. When we call a method the this keyword will point to the object on which the method is called, or it points to the object that is calling the method. Let's see an example below:

    const student = {
      name: 'Isaac',
      class: 'Junior',
      age: '16',
      callStudent: function () {
        return `${this.name} is ${this.age} years old`;
      },
    };
    console.log(student.callStudent()); // Isaac is 16 years old

In the example above, the method is the callStudent method because it is a function that is attached to the student object. We then called the method and console logged it. Inside the method, we used the this keyword, and we found the value of the this keyword to be student because it is the object that is calling the callStudent method. And that’s why this.name is Isaac because it means student.name and this.age is 16 because it means student.age.

2) Calling functions as regular functions:

This is probably the default way of calling function. The this keyword can have different values when used in a regular function call depending on whether you are coding in strict mode or default mode (non-strict mode).

  • In strict mode: Strict mode doesn't allow for default binding and therefore when used in strict mode, the this keyword in a regular function call is undefined
  'use strict';
    function myFunction() {
      console.log(this === undefined); // true
    }

    myFunction();
  • In default mode: When used in default mode, the this keyword refers to the global object, which in the case of the browser is the window object. Let us see an example below:
    function printThis() {
      console.log(this)
    }

    printThis()
// Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

Note: It should be noted that using this in default mode can be very problematic and can introduce bugs into your code because you aren’t sure where your this keyword is pointing. Therefore it is advised that you always write your Javascript code in strict mode.

3) In a Constructor

A constructor is a function that creates an object and initializes that object with a class. A constructor is called when an object is declared with the new keyword. The this keyword is set to the newly created object. Let’s look at the example below:

    function Sport(type) {
      this.type = type;
    }
    Sport.prototype.getType = function () {
      return this.type;
    };
    let sport = new Sport('Football');
    console.log(sport.getType()); // Football

In the code block above, we created an object with the new keyword, and then the this keyword was set to the newly created object (Sport). That’s why we could access this.type to get Football. The capital letter is used to show that the function is a constructor.

4) Using the call() and apply() method

All functions in Javascript are first class objects meaning that they have their own methods and properties. The call() and apply() methods are two of those methods. These methods lets you set the this keyword when calling a function irrespective of whether that function is being called in the global scope or as the object's method, as we will see in the example below:

    function getSport(prefix) {
      console.log(prefix + this.type);
    }
    let footBall = {
      type: 'Football!',
    };
    let cricket = {
      type: 'Cricket!',
    };
    getSport(footBall, "It's called ") //[object Object]undefined
    getSport(cricket, "It's called ") //[object Object]undefined

    getSport.call(footBall, "It's called "); // It's called Football!
    getSport.call(cricket, "It's called "); // It's called Cricket!

    getSport.apply(footBall, ["It's called "]); // It's called Football!
    getSport.apply(cricket, ["It's called "]); // It's called Cricket!

In the example above, we see that when we called the getSport function that it returned [object Object]undefined because there is no connection between getSport, footBall, or cricket. Therefore, the this keyword will result in undefined in strict mode or to the global object in default mode. However, when we use call() and apply(), we invoke the this keyword of footBall and cricket on the getSport function.

Note: The difference between apply() and call() method is that apply() takes in arguments as an array while call() requires arguments to be passed in one by one.

Other ways in which the this keyword can be referenced

The this keyword can also be referenced in other ways apart from when functions are called, and we are going to discuss them in this section.

Arrow functions

Arrow functions do not get their own this keyword. Instead, if you use the this keyword in an arrow function, it will simply be the this keyword of the surrounding function (the parent function). Technically it is known as the lexical this keyword because the arrow function inherits the this keyword from the outer lexical scope (function).

    const sayName = {
      name: 'Isaac Junior',
      regularFunction: function () {
        console.log(this.name);
      },
      arrowFunction: () => {
        console.log(this.name);
      },
    };
    sayName.regularFunction(); // "Isaac Junior"
    sayName.arrowFunction(); // undefined

In the example above, we created an object with two functions set as methods. When we called the first function which was a regular function, we notice that the this keyword pointed to the object that was calling the method and that was why we got Isaac Junior in the console. But when we called the second function which was an arrow function, we notice that we get undefined or nothing in the console and that is because arrow functions do not have their own this binding.

Using the bind() method

Sometimes, you might need to use a method over and over with the this context of another object, and in that case, you could use the bind method to create a brand new function with an explicitly bound this. Let’s look at an example below:

    let gender = {
      type: 'male',
      getType: function () {
        return this.type;
      },
    };
    let seaAnimal = {
      type: 'Octupus',
    };
    let type = gender.getType.bind(seaAnimal);
    console.log(type()); // Octupus

In the example above, we bound the this keyword to the seaAnimal object. And that's why the value of the type property is that of the seaAnimal object in the console

Event Handlers

The this keyword will always point to the DOM element that the handler function is attached to in event handlers. Let’s see an example below:

const words = document.getElementsByClassName('tags');
function turnBlue() {
  this.style.backgroundColor = '#A5D9F3';
}
for (let i = 0; i < words.length; i++) {
  words[i].addEventListener('click', turnBlue);
}

In the example above, we have an event listener that turns any class with tags in our code blue when we click on it. We used the this keyword, and as we can see, it points to the DOM element on which the event listener or handler is attached which in this case is words.

Conclusion

In this article, we have looked at and broken down what the this keyword is, and what it points to in every instance in which it is created. I hope that you will be more confident about making use of the this keyword from now onwards whenever you are writing Javascript code.