My Widow's mite: The "this" keyword in Javascript
Tags: javascript, functional, beginners, believer
Published: 2021-08-24 12:39:07

> “Truly I tell you, this poor widow has put more into the treasury than all the others.
They all gave out of their wealth; but she, out of her poverty, put in everything— all she had to live on.”

> *Mark 12: 43-44*

Warning, this is the most naïve approach but in the end, I hope to better help you understand the *this* keyword even in cases where it proves most elusive to understand.

I'm writing this passionately because I've witnessed firsthand, the muddling that comes with the *this* keyword in context and reference.

The word *This* by itself  is a demonstrative pronoun which is used for indicating (point to) something. To understand you need to first grasp the concept of pronouns and how it saves you from looking like a complete fool on a daily basis 😁.

Consider this example: *Richard scored highest in the test because Richard read all through the night.*

Implementing the concept of pronouns as a sane person would, we write: *Richard scored highest in the test because* **he** *read all through the night.*

Notice how we didn't reuse *Richard*, we do this because we don't want people to run away from us. Trust me, any guy that does otherwise should bid farewell to his chances of landing a pretty model-like girlfriend 🤦‍♂️.

So it is in JavaScript and programming in general, hence the need for a referent. The *this* basically refers to an object (an antecedent) which is the subject in the context of an executing code. 

Here is an example to help you further understand:
```javascript
let person = {
    name: 'Richard Doe',
    job: 'Farming',
    jobFunction: function () {
      console.log(`${this.name}'s occupation is ${this.job}`);
    },
  };
  person.jobFunction(); //Richard Doe's occupation is Farming

  // But of course this would also work
  let person = {
    name: 'Richard Doe',
    job: 'Farming',
    jobFunction: function () {
      console.log(`${person.name}'s occupation is ${person.job}`);
    },
  };
  person.jobFunction(); //Richard Doe's occupation is Farming
```
Our code becomes superfluous writing it the second way as *person.name* and *person.job*, definitely a turnoff 🤮. Especially since there could be another global variable *person* that we might not be aware of and this could lead to difficult-to-debug errors in our code. So we use the *this* keyword to avoid ambiguity and emphasize precision, yeah and also for aesthetics (at least in my own case).

Like objects all JavaScript functions have properties. And when executing, they get the *this* property __ a variable with the value of the object that invokes the function where *this* is used.

``When in strict mode, "this" holds the value of undefined in the global scope and anonymous in functions that aren't bound to any object.``

##GOTCHA 

To expunge every confusion it is important that you understand this one principle; **this** *is not assigned a value until an object invokes the function where this is defined*.
In most cases *this* assumes the value of the object that invokes it. There are only few instances or scenarios when *this* does not have the value of the invoking object and I'll touch on some of them here and drop a link to an article for a more in-depth and probably more comprehensive article.

### *this* in global scope
This is getting too lengthy yeah? Just one more section with few points and we are done, **Arigato** 🙏.

In the global scope all global variables and functions are defined in the window object. Hence, in the global scope *this* will have the value of the global window object (except in strict mode).
```javascript 
  // in the global scope
function print() {
    this.color = 'purple';
    console.log(this.color);
  }
  print(); //purple
```
in strict mode: 
```javascript
 function print() {
    'use strict';
    this.color = 'purple';
    console.log(this.color);
  }
  print();//Cannot set property 'color' of undefined
```
Here comes the tricky part, now I'll be touching on some scenarios where the *this* keyword becomes confusing.

*  When "this" is used in a method passed as a callback.

Things get touch hairy when we pass a method (that uses *this*) as a parameter to be used as a call back function.

Here is an example:

```javascript
 // here is an object with a clickhandler method that is called when a button is clicked
  var person = {
    farmers: [{ name: 'Richard Doe', job: 'Farmer' }],
    clickHandler: function () {
      console.log(`${this.farmers[0].name} is a ${this.farmers[0].job}`);
    },
  };
  let button = document.getElementById('button'); //button here is an object
  button.addEventListener('click', person.clickHandler); //the click() method here is a method on the button object and
  // Cannot read property '0' of undefined because there is no farmers property on the button object
```

*this* here is undefined because *button* is an object all by itself and *person.clickHandler()* is a method we are passing to *button*'s click method as a callback. This implies that the *person.clickHandler()* will no longer refer to the person object. *this* here will now refer to the object where the *person.clickHandler()* method is executed which is the button object.

Hence it is lucid that when the context changes the *this* keyword will no longer refer to the object where *this* was originally defined but to the object that invokes the method where *this* was defined.

An approach to resolving this problem is to use the bind method. We will bind the *clickhandler()* method to the person object.

Here is an example:

```javascript
 // An alternative approach
  var person = {
    farmers: [{ name: 'Richard Doe', job: 'Farmer' }],
    clickHandler: function () {
      console.log(`${this.farmers[0].name} is a ${this.farmers[0].job}`);
    },
  };
  let button = document.getElementById('button'); //button here is an object
  button.addEventListener('click', person.clickHandler.bind(person)); //the click() method here is a method on the button object and
  //Richard Doe is a Farmer
```

* When *this* is used inside a closure

Closures are inner functions basically and it is expedient you grasp that closures can't access the *this* variable of outer functions by using the *this* keyword because the *this* varaible can be accessed only by the function itself.

See this:

```javascript
  var person = {
    farmersMotto: 'Farming is our pride',
    farmers: [
      { name: 'Richard Doe', job: 'Farmer' },
      { name: 'Rachael Doe', job: 'Farmer' },
    ],
    clickHandler: function () {
      this.farmers.forEach(function () {
        console.log(`Our motto as farmers is ${this.farmersMotto}`); //Our motto as farmers is undefined
        //why?
        console.log('' + this); // [object window]
      });
    },
  };
  person.clickHandler();
```

*this* inside an anonymous function is bound to the global window object because  it cannot access the outer function's *this*(when strict mode is not in use)

Resolving this on the other hand is quite easy, just set the *this* value to a variable before entering the anonymous function. This is a fairly popular approach amongst developers.

See this:

```javascript
 var person = {
    farmersMotto: 'Farming is our pride',
    farmers: [
      { name: 'Richard Doe', job: 'Farmer' },
      { name: 'Rachael Doe', job: 'Farmer' },
    ],
    clickHandler: function () {
      var thisPerson = this;
      this.farmers.forEach(function () {
        console.log(`Our motto as farmers is: ${thisPerson.farmersMotto}`); //Our motto as farmers is: Farming is our pride
      });
    },
  };
  person.clickHandler();
```

* *this* when a method is assigned to a variable

Here is an example:
```javascript
  // This data variable is a global variable
  var farmers = [{ name: 'Rachael Doe', job: 'Farming' }];

  var person = {
    // this data variable is a property on the Person object
    farmers: [{ name: 'Richard Doe', job: 'Farming' }],
    showData: function (event) {
      console.log(`${this.farmers[0].name}'s job is ${this.farmers[0].job}`);
    },
  };

  // Assign the person.showData to a variable
  var showPersonsData = person.showData;

  //
  showPersonsData(); // Rachael Doe's job is Farming (from the global data array)
  //The output we desire is: Richard Doe's job is Farming. 
  //so how do we fix this?
```
A quick fix to this will be to use the bind method.

Like this:

```javascript
  // This data variable is a global variable
  var farmers = [{ name: 'Rachael Doe', job: 'Farming' }];

  var person = {
    // this data variable is a property on the Person object
    farmers: [{ name: 'Richard Doe', job: 'Farming' }],
    showData: function (event) {
      console.log(`${this.farmers[0].name}'s job is ${this.farmers[0].job}`);
    },
  };

  // Assign the person.showData to a variable
  var showPersonsData = person.showData.bind(person);

  //
  showPersonsData(); // Richard Doe's job is Farming (from the global data array)
```

Of course, there  are other cases of the Javascript *this* keyword errors and fixes. I recommend you read [this article](https://www.javascripttutorial.net/javascript-apply-method/) for an in-depth understanding of the *this* keyword.

## Final Note

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gwo2jd9y4c8ne3baghsx.png)

I'm inexperienced myself but I hope I have been able to help you out with the little I know. Lemme know what you think 👋.

>In everything I did, I showed you that by this kind of hard work we must help the weak, remembering the words the Lord Jesus himself said: ‘It is more blessed to give than to receive.

> *Act 20:35*