DEV Community

Cover image for Navigating the 'this' Maze in Javascript - Part 1
rohits1908
rohits1908

Posted on

Navigating the 'this' Maze in Javascript - Part 1

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()
Enter fullscreen mode Exit fullscreen mode

Output:

Output 1 - this within object

  • 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()
Enter fullscreen mode Exit fullscreen mode

Output:

Output 2 - this without object

  • 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')
Enter fullscreen mode Exit fullscreen mode

Can you guess the output for above example?

Output

Output 3 - this with new keyword

  • 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()
Enter fullscreen mode Exit fullscreen mode

Output:

Output 4 - this in forEach loop in javascript

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()
Enter fullscreen mode Exit fullscreen mode
  • 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


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

Top comments (0)