DEV Community 👩‍💻👨‍💻

Jamiebones
Jamiebones

Posted on • Updated on

What The Heck is This

The Javascript concept "this" happens to be a tricky one to fully grasp and understand. To fully understand it, some core Javascript internals must be understood.

  • Execution context
  • Scope
  • Lexical scope
  • Dynamic scope

Execution Context

Our Javascript code gets executed by the Javascript engine which creates an execution context. The execution context is like a small world or planet where our code run.

  function sayMyName(name){
    return name;
  }

//this simple function just returns the name passed on to it

Enter fullscreen mode Exit fullscreen mode


`
The Javascript engine creates an execution context for the function call of sayMyName (it does it for all function call). sayMyName function runs under the global execution context which provides access to two variables namely the global object (which is window on the browser) and the this keyword. Function sayMyName has access to the parent (Global Execution Context) variables.

Scope

A scope is the visibility of a variable meaning, where that variable can be accessed. Scope are of types lexical and dynamic scope.

`

   function sayGoodBye(){
     let goodbye = "au revoir";
   }

Enter fullscreen mode Exit fullscreen mode


`
The goodbye variable can only be accessed from the sayGoodBye function. It exists in its own world ( function execution context ). Where the function was defined determines the variables available to us in Javascript. This is what is called lexical scope.

Dynamic scope means, available variable is determined on how a function is called instead of how it was written. The "this" keyword is dynamic scoped and its value depends on who calls the function.

Let's see some code.....

`

   function CreateTeam(name, league, strength, points){
    this.name = name;
    this.league = league;
    this.strength = strength;
    this.points = points;
 }
//simple constructor function used for creating teams.

function displayStrength(){
  return `${this.name} is ${this.strength}`
}

displayStrength()
//will return ' is undefined'

Enter fullscreen mode Exit fullscreen mode


`
For the displayStrength() function to return something meaningful, it has to be called with an object that has a name and a strength property.

`

  let newTeam = new CreateTeam("Arsenal", "English Premiership", "solid", 80);

newTeam.strength = displayStrength;
//to display the strength of our team 

newTeam.strength();
//which returns the correct value of this and display\
//the right information.

//our displayStrength function was called with the\
//newTeam object and it displayed the correct value.

Enter fullscreen mode Exit fullscreen mode


`
The this keyword is the object that the function is a property of. The this keyword acts as a placeholder and resolves to whoever calls the function. What if our function returns another function; what will the value of this?

`

function displayStrengthTwo(rating){
   let accumulatedPoints = rating * 20;
   return function(){
      return this.points + accumulatedPoints;
  }
}

//attach the displayStrengthTwo to a new property on our team object.
newTeam.rating = displayStrengthTwo;
let rating = newTeam.rating(20)
//rating is a function
//call rating
let value = rating();
//value will be equal to NaN
Enter fullscreen mode Exit fullscreen mode


`
According to our definition of this above "The this keyword is the object that the function is a property of". The inner anonymous function is no longer attached to the object. It was returned from another function thereby getting the value of this from the global execution context.

We can fix this problem by returning an arrow function as the inner function.

`

//this function will return correctly beacuse the inner function is an arrow function that has a lexical scope bound.

function displayStrengthTwo(rating){
   let accumulatedPoints = rating * 20;
   return () => {
      return this.points + accumulatedPoints;
  }
}

newTeam.rating = displayStrengthTwo;
let rating = newTeam.rating(20)

//rating is a function
//call rating
let value = rating();
//returns the expected value.
Enter fullscreen mode Exit fullscreen mode


`
Arrow function has a lexical scope bound making them able to retain the correct value of this.

To wrap up, the this keyword has a dynamic scope whose value depends on the object calling the function. As my favourite online tutor (Tyler McGinnis ) will say, anything in front of the dot ( for example our rating function newTeam.rating ) determines the value of this.

Thanks for reading.....

Top comments (0)

Visualizing Promises and Async/Await 🤯

async await

☝️ Check out this all-time classic DEV post