Navigating the 'this' Maze in Javascript - Part 1
Tags: javascript, webdev, beginners, programming
Published: 2023-07-09 14:49:10

## Introduction

One of the most confusing mechanism in Javascript is understanding the `this` keyword. It is a special identifier defined in the scope of every function, but what it refers to sometimes even may confuse even the seasoned JS developers.

Let's try to simplify and understand the `this` mechanism.

## What is `this`?

In simple words:

> `this` is the object executing in the current function

Remember these simple thumb rules:

- If the executing function is a method an object then `this` refers to that object itself (1)
- Otherwise if it is a regular javascript function i.e. it is not a member function then `this` refers to the global object which is `window` in browser and `global` in Node (2)

Let's try to understand the above thumb rules through series of examples

---
**Example (1)**

```
const song = {
    title: 'song title',
    play() {
        console.log(this)
    }
}

song.stop = function() {
    console.log(this)
}

song.play()
song.stop()
```
**Output**:

![Output 1 - this within object](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2azwvol9f47hngwical.jpg)

- We have a `song` object with `play()` as method function. We have added another `stop()` function to the same object.
- Since the `this` is inside method function it points to the `song` object.

---

**Example (2)**

```
function playSong() {
    console.log(this)
}

playSong()
```
**Output**:

![Output 2 - this without object](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82osy316z60nrjtmm6ak.jpg)

- We have a `playSong()` function which doesn't links to any object.
- In this case `this` links to the `window` object in browser.

---
**Example 3**

Let's Modify the above code to look something like: 

```
function Song(title) {
    this.title = title
    console.log(this)
}

const songObj = new Song('song title')
```
Can you guess the output for above example?

**Output**

![Output 3 - this with new keyword](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rwad3dqcvf0l4xljfr67.jpg)

- We have a `Song()` function which doesn't belong any object in the initially but later we create a `songObj`
- `songObj` is initialised using a `new` keyword which creates an empty object and then points `this` to the `{}` empty object.
- Finally we add the `title` property to `this` object.

---

**Example 4**

Let's take a look at another example:

```
const song = {
    title: 'song title',
    comments: ['x', 'y', 'z'],
    showComments () {
        this.comments.forEach(function(comment){
            console.log(this.title, comment)
        })
    }
}

song.showComments()
```
**Output**:

![Output 4 - this in forEach loop in javascript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shh5s6lu8zp3ut273fm0.jpg)

What is going on in the above example?

- If you remove `title` from above example in `console.log()` you can see that the `this` actually now points to the global (`window`) object.

- But we're inside the `song` object shouldn't the `this` point to `song` object?

- If you look at the function inside the `forEach` loop it is just a regular javascript function, it is not a method inside the `song` object. The `song` object only has one method `showComments()`.

- So the `this` inside the anonymous callback function inside `forEach` loop holds context to the global object.

**Now you must be wondering how can we solve this problem?**

```
const song = {
    title: 'song title',
    comments: ['x', 'y', 'z'],
    showComments () {
        this.comments.forEach(function(comment){
            console.log(this.title, comment)
        }, this)
    }
}

song.showComments()
```
- The second argument in the `forEach` takes the context info, so when we call the `showComments()` while passing `this` as the context we're still in the execution context of `showComments()`.
- Now when you run the above code look at output.

**Output**:


![Output 4 - fixing this in forEach](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ql2003i0opl01gfn6vom.jpg)

---

Now every function in javascript doesn't accept the context argument, so how can we change the `this` context in javascript during runtime, will be covered in the next part (Part 2).

Thank You for Reading. Happy Learning!

**References**: Mosh Hamedani - JavaScript Fundamentals