This, Hoisting and Execution Context in JavaScript

SVRourke
JavaScript in Plain English
4 min readFeb 28, 2021

--

Photo by Markus Spiske on Unsplash

This

If you’ve been learning JavaScript you’ve probably run into “this” a few times, usually with a minimal explanation followed by something along the lines “don’t worry about how this works it’ll make more sense later on”. Well now it’s later on, so what is this?

This: A property of an execution context (global, function or eval) that, in non–strict mode, is always a reference to an object and in strict mode can be any value. -MDN docs

To understand what that means you have to understand how JavaScript executes code. Let’s start with a basic understanding of this, different examples of this and manually setting the value of this, then we’ll move on to execution contexts and finally hoisting.

An easier way to explain the MDN quote would be to say the value of this for a function is the context in which it is called, for an event listener this is the element the listener is attached to and for a method this is the object that owns the method.

function returnThis () {
return this
}

In this example invoking returnThis would return the window object (in a browser) as the function is declared in the global context and thus belongs to the global object meaning it is not declared within another function or object.

class WhatIsThis {
returnThis () {
return this
}
}
let test = new WhatIsThis

In this example, the test.returnThis() returns the the instance of WhatIsThis referenced by “test” as WhatIsThis is the object that owns the returnThis() method.

function log () {console.log(this)}const button = document.querySelector('button');buttons.addEventListener('click', log);

For this example imagine we have a webpage that contains a single button with an event listener that invokes the log function when triggered. You try it with this codepen I made, you will see that the button DOM element is logged to the console when the button is pressed. This is because the value of this within event listeners is the element the listener is attached to, however, if we were to run log() directly in the console without using the event listener it would return the window object. This is because the value of this within a function is determined by the context in which it is invoked meaning that when log() is invoked within the event listener the value of this within log is the DOM button element!

function external () {
return this.name
}
let person = {
name: "Sam",
age: 27
}
let sam = external.bind(person)console.log(sam())

This code sample show manually setting the value of this using .bind(), using a.bind(b) would return a new function with the same body and scope as a but where this is the same as in b. In this code sample we define the function external which returns this.name, if external were invoked as-is it would return an empty string. We also created an object ‘person’ with two attributes: name, and age. Next we use bind() to create a new function called sam using the this of person with the function external. by calling sam() you will see that the name attribute of the person object is returned.

Execution contexts

When you run a script you might think the JavaScript engine runs your code line by line executing code as it goes, however this is incorrect as the JavaScript engine operates in two phases: creation and execution.

const myName = 'Sam';function greet (name) {
return `Hello ${name}`;
}
const greetSam = greet(myName);
console.log(greetSam)

We’ll walk through this code step by step the same way the JavaScript engine would. When you execute this script for the first time JavaScript creates the first execution context, the global execution context and binds it to the keyword this, it also allocates memory to the variables myName and greetSam and the function declaration for greet(), however it stores the variable as undefined.

After the Creation phase JavaScript moves to the execution phase, where it assigns values to the variables and executes the function calls. Every time JavaScript reaches a function call it creates new execution context for the function, again undergoing a creation and execution phase for each new context, returning the resulting value to the global execution context which continues to execute the code remaining. To continue our example after moving to the execution phase the JavaScript engine will:

  1. assign the string ‘Sam’ to the variable myName.
  2. create a new execution context for the invocation of greet() in greetSam
  3. execute the context for the invocation of greet()
  4. return the result of greet() to the global execution context.
  5. assign the returned value to the variable greetSam
  6. log the value of greetSam to the console

Hoisting

Hoisting is a way to conceptualize the way that JavaScript builds execution contexts affects when variables and functions are available during the execution of code. The way the creation phase puts all of the variables and functions into memory before executing the code makes it appear as though all of your variable and function declarations are “Hoisted” to the top of the file for example:

greetUser()function greetUser () {
console.log('Hello')
}

In this example the greetUser() function is invoked before it is even written, you would intuitively expect this to result in an error, however during the creation phase the greetUser declaration was hoisted before the invocation was executed.

Only declarations are hoisted:

console.log(x) // Undefined
var x; // Declaration
// let & const not hoisted, cannot reference before init
// const must have initializer in declaration
console.log(y) // ReferenceError
let y = 6; // Declaration and Initialization NO HOIST

With a basic understanding of the way JavaScript executes code Hoisting should be fairly straightforward concept.

Conclusion

Hopefully this post has helped someone get a better understanding of This, Hoisting, and JavaScript code execution on a whole, I know it has definitely helped me.

If you enjoyed my writing feel free to check out my website and connect with me on LinkedIn

More content at plainenglish.io

--

--