Explained : Javascript 'this' keyword to a 12 year old!

Hello, this is my first JS blog. Looking forward to the feedback.

Please donot proceed if you are less than 12 year old.

The concept of this has irritated me for a long time and messed up lot of my interviews. So I just tried to sit and console.log things on my own one day and understood enough to answer the interview questions. To be frank, I havent used this concept enough in day today coding. I only use it during any weird error debugging by changing arrow function to normal function and vice-versa. Like if you too agree on my above words.

So lets start then. Overall, you just need to understand 3 main behaviours of this keyword.

  1. How it behaves in normal defined function.

  2. How it behaves in arrow defined function.

  3. How it behaves in async callback function.

    How it behaves in normal defined function


/* 
    myFunction1 & myFunction2 are normal defined function. 
    'this' behaves same in both the cases/
*/

const myFunction1 = function() {
   console.log(this);
}

function myFunction2() {
   console.log(this);
}

myFunction1(); // prints window
myFunction2(); // prints window

const myObj = {
    name: 'abc',
    myFunction1: myFunction1,
    myFunction2: myFunction2,
}

myObj.myFunction1(); // prints myObj
myObj.myFunction2(); // prints myObj

Main points to remember:
a) this will always point to window object if called directly.
b) this will always point to object if called from object. ( Eg : myObj.myFunction1(); )

How it behaves in arrow defined function

// arrow function
const myFunction1 = () => {
    console.log(this);
}

const myObj = {
    name: 'abc',
    myFunction1: myFunction1,
}

myFunction1(); // prints window
myObj.myFunction1(); // prints window

/*
 Both the times the function above are called/invoked in window scope. 
 Hence it prints window object.
*/

Main points to remember:
a) this will always point to object from where the function is called/invoked.

How it behaves in async callback function.

function myFunction1() {
    // this => points to myObj since myFunction1 is normal defined function.

    setTimeout(() => {
        console.log(this); // prints myObj
        /*
           Why myObj?
           because it is getting called/invoked in scope of myFunction1 and 
           'this' of myFunction1 is pointing to myObj
        */   
    }, 2000);

    setTimeout(function callback() {
        console.log(this); // print window
        /*
           Why window?
           because callback is called/invoked directly without any object and
           'this' will always point to window object if called directly.
        */   
    }, 2000);
}


const myObj = {
    name: 'abc',
    myFunction1: myFunction1, 
}

myObj.myFunction1();

Main points to remember:

a) Nothing to remember. Just the application of behaviours 1 & 2.

Revision Example

const myFunction1  = function() {

    const abc = function(){
        console.log(this);
    }

    const xyz = () => {
        console.log(this);
    }

    abc();
    xyz();
}

const myObj = {
    name: 'abc',
    myFunction1: myFunction1, 
}

myObj.myFunction1();

What will 'this' of myFunction1 point to ?

It points to myObj because myFunction1 is normal defined function and is called from myObj. (myObj.myFunction1();)

What will 'this' of abc point to ?

It points to window because abc is normal defined function and is called without any object. (abc();)

What will 'this' of xyz point to ?

It points to myObj because xyz is arrow defined function and is called inside or in the scope of myFunction1 which is pointing to myObj.

Note : If myFunction1 was an arrow function, 'this' would point to window and similarly 'this' of xyz would also point to window.

Conclusion

You just have to remember and understand the points mentioned for first 2 behaviours. Rest all is the application and combination of it.