"This" keyword in Javascript - an explanation
Tags: this, javascript, beginners, developer
Published: 2020-04-10 19:21:36

What is `this` and why is it so confusing to understand? Simply put, `this` keyword refers to the object that is executing the current function (the "owner" of the function). Well ok, now in plain English?

Let's just say that `this` is dependent on the context in which is used. If we find it in a regular function (we make a simple function call), it references the global object (called **window** in browsers and **global** in Node) and if we find it inside a method (a function inside an object), it will reference that object.

For a better understanding, I recommend you try the code below in the console. _**Note that I'm using the syntax prior to ES6 for writing functions.**_

```javascript
function printKeyword() {
  console.log(this);
}

printKeyword(); // prints the window object

const someObject = {
  someProp: 'random',
  someFunction() {console.log(this)}
}

console.log(someObject.someProp) // prints random
someObject.someFunction(); // prints {someProp: "random", someFunction: ƒ}

```

In the first example, `printKeyword` it's not a method on an object so, as expected it will print the window object to the console. In the second example, `someFunction` is a method on `someObject`, so when trying to log `this` we'll print the object itself.

If we put it this way, it's not too complicated, right? So why all the fuss? Of course, these are very simple examples so let's take it up a notch.

```javascript

const myDoggo = {
  name: 'Lulu',
  age: 3,
  hobbies: ['sleeping', 'TV', 'swimming'],

 printName() {
   console.log(this.name)
},

 printAge() {
   console.log(this.age)
},

 printHobbies() {
   console.log(this.hobbies)
},

 printAgeAndHobbies() {
   this.hobbies.forEach(function(hobby) {console.log(hobby + this.age)})
}
}

myDoggo.printName() // prints Lulu
myDoggo.printAge() // prints 3
myDoggo.printHobbies() // prints ["sleeping", "TV", "swimming"]
myDoggo.printAgeAndHobbies() // prints sleepingundefined TVundefined swimmingundefined

```
We have an object with two properties and four methods. You might notice that the first three methods seem to work perfectly fine but when we get to `printAgeAndHobbies` we might have a surprise. Trying to log `hobby + this.age` prints the hobby but not the age. Actually we get `undefined`.

This is because `this.hobbies` is inside `printAgeAndHobbies`, which is a method on the `myDoggo` object. But `this.age` is also inside the same method, you might say. Well, yes and no. 

`this.age` is actually inside a call back function which is inside the `forEach`  method inside the `printAgeAndHobbies` method. Say what? So, we are using a method called `forEach`. It works with arrays and calls an anonymous function (callback) on every item of the array. So technically, the callback inside which `this.age` is used is a regular function and not a method on an object. I hope that's clear. 

The way we can fix this particular situation is by adding a second parameter to the forEach method (the first one being the call back function). We can pass an object as a second argument and the callback will reference that object. In our case the second argument will be `this`. As said before, every `this` we put inside a method on an object refers to that object. Since the second argument will be in the context of the `printAgeAndHobbies` method, it will reference the `myDoggo` object. Check the code bellow:

```javascript
printAgeAndHobbies() {
   this.hobbies.forEach(function(hobby) {console.log(hobby + this.age)}, this)
}

myDoggo.printAgeAndHobbies() // prints sleeping3 TV3 swimming3
```
I know it's a lot to wrap your head around, so I'm going to stop here for now. If something is still unclear, please ask in the comments and I'll try to give it another shot at explaining. In the next text we'll discuss more fixes and maybe introduce the ultimate fix, the ES6's fat arrow function.