Know what happens to your JavaScript code under the hood πŸ˜‰

Know what happens to your JavaScript code under the hood πŸ˜‰

Hello World, Akwaaba πŸ‘‹. In today's post, we will learn about the JavaScript execution context to understand how JavaScript code gets executed. Having a good grasp of the JavaScript Execution context will make many complex topics like hoisting, scope, scope chain, and closure very easy to understand.

We will take a look at what it is, its type, how the execution context is created, and the execution phases. You should have a firm grasp on how JavaScript works under the hood after this article.

With that in mind, let's try to understand what the Execution Context is.

What is the Execution Context?

When a source code is written and run in a browser, the JavaScript engine in your web browser reads this source code and compiles it into machine-readable code. After the code has been parsed(read) and compiled, it is now time to execute the piece of code. This execution will happen in an execution context.

Before we define the Execution context, let's break the word into two, execution and context

What is Execution?

Execution is basically how the computer CPU processes the piece of code it has received.

What is Context?

In the English language, context basically talks about the circumstances, surroundings, conditions, or environment. Now that we have understood what execution and context are in the English language, let's define the Execution context in JavaScript.

What actually is the JavaScript Execution Context?

The Execution Context deals with the environment, surrounding, or circumstance in which a piece of code the computer has received is processed.

It deals with how sections of the code such as functions, variables, and Objects are processed.

When the execution context is being run, it has access to some variables, functions, and Objects used in the code.

Execution context can be seen as the container which stores all necessary information needed for a piece of code to be processed.

As an analogy, think of ordering a pizza πŸ• at your favorite eatery. When you order the pizza, it will come wrapped in a box. The box is the container or the environment in which the pizza will be consumed. The box also contains all the things needed to consume the pizza. The pizza then becomes the piece of code to be executed. The box may also contain some receipts (analogy for variables)so you can remember how much you purchased the pizza and some fork and knife( analogy for functions) to help you consume your pizza.

These internal details are what we will loosely describe as the execution context of the pizza. So like, was said previously, the execution context stores all the necessary information for some code to be executed.

Why the need for an execution context?

Developers always like to write code that is maintainable, not complex, and follows best practices. With the execution context in place, the JS Engine is able to manage the code better, resolve any complexities as well as identify bugs so it can easily be fixed.

Using the Pizza analogy, its execution context will help us know, whether we need to have a look at our receipt or check if there is a pile of tissue added to our package before consuming our pizza (we don't want any surprises 😲 ).

So when a piece of JS code is being run, we need to take a look at the execution context, which informs us how to manage or process the code.

Alright, now let's take a look at the types of the execution context.

Types of execution context

There are three main types of execution context

  • Global Execution Context
  • Function Execution Context
  • Eval Execution Context

First, we take a look at the Global Execution Context

The Global Execution Context (GEC)

When you first run your JavaScript code, it will create a container called the Global Execution Context Any piece of code which is not defined inside a function or in a block will be created in the Global execution context or default execution context.

Any code outside of a function definition will be created in the global execution context.

The Global execution context consist of two phases

  • Creation Phase
  • Execution Phase

Let's now talk about the first phase: Creation Phase

Creation Phase of the GEC.

Every piece of code begins its execution when the JavaScript file first loads in the browser, in the creation phase of the GEC the following will occur:

  • First, it creates a global object named window for the browser and
  • Secondly, it creates a global variable called this.
  • If there is a variable declaration in the code, it allocates memory for the variable, initializes the variable, and sets it to a default value of undefined.
  • Lastly, if there is a function in the code it will store it in the memory for later execution.

Execution Phase of the GEC

After the creation phase, the execution phase kicks in.

The execution phase is where the actual code execution starts.

At this phase, the JS engine executes the code line by line. The below happens at this phase:

  • Values will be assigned to the initialized variables

  • function calls are executed.

Something interesting happens when the execution gets to a function call. When the execution gets to a function call (Eg. getName()), the JS engine will immediately create a function execution context. It is in this function execution context we will then work on the function call. 😁. So even though, we have access to the function in the global execution context, it will not be executed yet. πŸ˜‰

Let's try to simplify all we have learned about the Global execution context with some examples

Understanding The Creation and Execution phases of the Global Execution Context

Example 1: Loading an empty JS file

To understand the GEC better, let's create an empty JS file and load it in a browser. Follow the steps below :

  • Create an index.html file
  • Add an empty script.js file to the index.html file
  • Load it in your preferred browser.

The code below captures the steps above

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>Understanding the Global Execution Context</h1>
    <script src="script.js" />

</body>
</html>

Alright, now let's find out what happens in the JS engine when the file has been loaded in the browser 🚢.

Now that you have loaded your file in the browser, the JS engine kick starts the execution context with the first being the Global execution context. As mentioned above, in the creation phase of the GEC, four main things happen, but let's focus on just two for now

Window object and this

  • Creation of the global object called window
  • Creation of the global variable called this

Ok, so follow the steps below to see if the window object was created in the creation phase

  • Open your browsers' developer tools.

  • Browse to the console tab

  • In the console tab, type window and press enter

If you have followed the steps correctly, you should see the below in your console

window
Window {window: Window, self: Window, document: document, name: "", location: Location, …}

The above is the window object we mentioned during the creation phase, now let's take a look at the next one, the this variable.

  • In the same console tab, type, this and press enter, you should see the below
this
Window {window: Window, self: Window, document: document, name: "", location: Location, …}

So, what did we learn from the above,

  • Whenever we load a JS file, the Global execution context gets created, even if the file is empty.
  • The creation phase, creates two specials things for us, the window object and the this variable
  • The window and the this variable all return the same object, in the Global execution context
  • When the file enters the execution phase, there is nothing to execute as the script.js is empty ☺️.

Alright, hopefully, you clearly understood the first example? You can actually visualize what is happening under the hood using this great javascript visualizer resource . Just click on run to see the result. 1626091077912.png

Let's now declare some function and variable in the script.js file and see what happens at both the creation and execution phases

Example 2. Loading a script with a variable and a function

Let's use the JavaScript visualizer to see what happens in the creation phase when you add a variable and a function to your script.

To the following in the console of the visualizer

  • Initialize a variable and assign a value to it.
  • Define a function
  • Now click on the step menu and visualize the result in the right pane.

The code below can be used

var user= "Emma";
function userGreeting(){
console.log("hello user");
}

The steps below sum all that will happen in the creation phase if you add a variable and a function to your script and you run it

  • The global window object and the this variable gets created ( as explained above ☝️)
  • Memory gets allocated for the variable user and the function userGreeting with our code above
  • The user variable gets initialized and assigned a value of undefined
  • The function userGreeting gets placed in memory (it will be executed later )

this.png

In summary, four main things happens in the creation phase of the global execution context:

  • First, it creates a global object named window for the browser and
  • Secondly, it creates a global variable called this.
  • If there is a variable in the code, it allocates memory for the variable, it initializes the variable and sets it to a default value of undefined.
  • Lastly, if there is a function in the code it stores it in the memory.

Now that we know all that happens in the creation, phase, let's take a look at what happens in the execution phase.

What happens in the execution phase of the GEC?

In the execution phase:

  • The variable will be assigned a value

  • The function has been defined and stored in memory, but because we have not called in yet, the execution does not take place. The execution will occur in the function execution context when we call the function

Go back to the code in your visualizer, and click on the "step" menu. You will see the code being executed gradually, moving from the creation phase to the execution phase.

When it finally reaches the execution phase, this is what you will notice in the right pane

  • The user variable will be assigned a value of Emma

  • The function userGreeting will be stored in the memory but will only execute when called, and that process will kick starts the function execution context

executionContex2.png

So far, we have talked about the Global execution context, let's now take a look at the next context, function execution context

The function execution context

When a function is called, the function execution context begins.

Let's see what happens with our code when there is a function call.

In the function execution context we will still have our two phases, the creation phase and the execution phase.

If any parameters have been passed to the function, the function execution context will have access to a special variable called arguments which is an object.

  • The arguments object contains a reference to all the parameters passed to the function.
  • If no arguments were passed to the function like in our example code, the length of the argument object will be 0
  • When a function invokes another function a new function execution context gets created for the new function call

So let's go back to our JS visualizer, call the userGreeting function and click on "run" or 'step" menu

  • Call the userGreeting function like userGreeting()

Below captures what will happen when the userGreeting() is invoked

  • We enter the creation phase of the function execution context
  • So, in our case, we will now be in the userGreeting Execution context
  • We now have access to the block statement of the function.
  • We enter the execution phase of the block statement and execute the code in it.
  • The arguments object gets created
  • We still have access to the this variable and the window object

JavaScriptExecutionContex4.png

Passing arguments to the function

Ok, now let's see what will happen when you give the function some parameter and pass in an argument

let user= "Emma"
function userGreeting(friend){
console.log("hello", friend);
/* hello, Emma* /
}
/*call the function and pass in the user variable as argument */
userGreeting(user)

Below is what happens in the execution phase of the userGreeting function execution context

  • Every code in the block statement of the function will be executed
  • With the code above, we pass the value of user as the argument to the friend parameter
  • The argument object will be created and will have the usual key-value pair in our code0: "Emma" `
  • The length of the argument will be 1

JavaScriptExecutionContex5.png

In summary, the function execution context kicks in when a function call is initiated The execution context will then be removed when the associated function has returned or execution is over.

Each of the function execution contexts determines the scope of the variables used in the respective functions.

Eval Execution context

Any JS code that gets executed within the eval function creates and holds its own execution context. However, the eval function is not really used by JavaScript developers, but it is part of the Execution Context.

In conclusion

In summary, we have learnt that

  • The execution context, is basically an environment or the container which stores all the needed information for the JavaScript code to be evaluated and later processed.
  • The execution context gets created when you run a piece of code in a web browser.
  • The default execution context is the Global execution context which has both the creation phase and execution phase. -The are three types of execution context, the Global Execution Context, Function Execution Context and Eval Execution Context.
  • The execution context helps you know what is happening under the hood of your code. Knowing what is happening enables you to fix bugs easily.
  • A great way to learn and see how code is being executed line by line is to use JavaScript Visualizer

Did you find my article insightful, please help spread the word by sharing on your social platforms. I would also love to read comments and feedback from you. Me daa se

PS: Akwaaba and Me daa se are Ghanaian πŸ‡¬πŸ‡­ dialect meaning, Welcome and Thank you respectively ❀️