Understanding the Basics of Code Execution in JavaScript

Understanding the Basics of Code Execution in JavaScript

ยท

8 min read

Javascript Execution Context

  • The topic is very important for those who are Javascript developers or want to have a deep knowledge of the working process of Javascript

  • Here, in this section, we will learn and understand the execution context of Javascript, Where we will discuss what it is, its types, its execution stack, how the execution context is created and all about the execution phase. We will discuss each point one by one. Let's begin with the introductory part first.

What actually is an execution context?

  • Execution Context is the concept for describing the internal working of code. In Javascript, the environment that enables the Javascript code to get executed is what we call Javascript Execution Context. It is the execution context that decides which code section has access to the function, variables, and objects used in the code. During the Execution Context, the specific code gets parsed line by line then the variables and functions are stored in the memory. An Execution Context is similar to a container that stores variables, and the code gets evaluated and then Executed. Thus, it is the Execution Context that provides an environment for the specific code to get Executed.

Types of Execution Context:-

The types of Execution Context in javascript are:-

  • Global Execution Context/ GEC

  • Functional Execution Context/FEC

  • Eval Execution Context

Global Execution Context

GEC / Global Execution Context is also called the base/defult execution. Any Javascript code which does not reside in any function will be present in the gobal Execution Context. The reason behind its name 'default Execution Context' where the code begins its Execution when the file first loads in web browser. GEC performs the two following tasks:

  • Firstly, it creates a global object where it is for Node.js and window object for the browsers.

  • Secondly, refernce the windows object to 'this' keyword.

  • Create a memory heap in order to sore variables and function references

  • The it stores all functions declarations in the memory heap area and the variables in the GEC with intial values as 'underfined'.

With the above introduction, one should understand that the Global Execution Context is only one in every code because the JS engine is single-threaded, and thus, only one global environment is possible for executing the JavaScript code.

Functional Execution Context

  • FEC or Functional Execution Context code is that type of context which is created by the Javascript engine when any function cal is found. Every function has its own execution context, and thus unlike GEC, the FEC can be more than one. Also, FEC can access the entire code of the GEC, but it is not possible for GEC to access all the code of the FEC> Druing the GEC code execution, a function call is when found by JS engine, create a new FEC for that specific function.

Eval Function 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 used by the JavaScript developers, but it is a part of the Execution Context.

Execution Stack

  • The execution stack is also known as Call Stack.
  • The stack is the data structure that stores the values in the form of LIFO (last in, first out). Similarly, an execution stack is a stack that carries track of all the execution contexts developed during the script life cycle. A JavaScript developer must be known of the fact that JavaScript works as single-threaded where it is capable of executing a single task in the web browser at a time. Thus, for other actions, functions, and events, a stack is created and is known as the Execution Stack.

Example:-

let x = 'Hello World!';  
function a() {  
  console.log('It is the first function');  
function b() {  
  console.log('It is the second function');  
}  
b();  
}  
a();  
console.log('It is GEC);

How are Execution Contexts Created?

  • Now that we are aware of what Execution Contexts are, and the different types available, let's look at how the are created.

  • The creation of an Execution Context (GEC or FEC) happens in two phases:

  1. Creation Phase

  2. Execution Phase

Creation Phase

  • In the creation phase, the Execution Context is first associated with an Execution Context Object (ECO). The Execution Context Object stores a lot of important data which the code in the Execution Context uses during its run-time.

  • The creation phase occurs in 3 stages, during which the properties of the Execution Context Object are defined and set. These stages are:

  1. Creation of the Variable Object (VO)

  2. Creation of the Scope Chain

  3. Setting the value of the this keyword

Creation Phase: Creation Of The Variable Object (VO)

  • The Variable Object (VO) is an object-like container created within an Execution Context. It stores the variables and function declarations defined within that Execution Context.

  • In the GEC, for each variable declared with the var keyword, a property is added to VO that points to that variable and is set to 'undefined'.

  • Also, for every function declaration, a property is added to the VO, pointing to that function, and that property is stored in memory. This means that all the function declarations will be stored and made accessible inside the VO, even before the code starts running.

  • The FEC, on the other hand, does not construct a VO. Rather, it generates an array-like object called the 'argument' object, which includes all of the arguments supplied to the function. Learn more about the argument object here.

  • This process of storing variables and function declaration in memory prior to the execution of the code is known as Hoisting. Since this is an important concept, we'll talk about it briefly before moving on to the next stage.

1. Hoisting in JavaScript

  • Function and variable declarations are hoisted in JavaScript. This means that they are stored in memory of the current Execution Context's VO and made available within the Execution Context even before the execution of the code begins.

Function Hoisting

  • In most scenarios when building an application, developers can choose to define functions at the top of a script, and only later call them down the code, like so:
function getAge (YearofBirth) {
console.log(New Date().getFullYear() - YearofBirth )
}
getAge(2004)
17
  • However, due to hoisting, the opposite will still work. Where we can call functions first then define them later down the script.
getAge(2001)
function getAge (YearofBirth) {
console.log(New Date().getFullYear() - YearofBirth )
}
22
  • In the code above, the getAge function declaration will be stored in the memory of the VO, making it available for use even before it is defined.

Variable Hoisting

  • Variables initialized with the var keyword are stored in the memory of the current Execution Context's VO as a property, and initialized with the value undefined. This means, unlike functions, trying to access the value of the variable before it is defined will result in undefined.
console.log(greetings)
var greetings = "Hi, i'm Victor. Nice to see you here";

Undefined

Ground Rules of Hoisting

  • Hoisting only works for function declarations, not expressions. Here is an example of a function expression where the code execution will break.
getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
  • The code execution breaks, because with function expressions, getAge will be hoisted as a variable not as a function. And with variable hoisting, its value will be set to undefined. That's why we get the error:

  • Also, variable hoisting does not work for variables initialized with the let or const keyword. Trying to access a variable ahead of declaration and use the let and const keywords to declare it later will result in a ReferenceError.

  • In this case, they will be hoisted but not assigned with the default value of undefined. js console.log(name); let name = "Victor"; will throw the error:

Creation Phase: Creation of The Scope Chain

  • After the creation of the Variable Object (VO) comes the creation of the Scope Chain as the next stage in the creation phase of an Execution Context.

  • When a function is defined in another function, the inner function has access to the code defined in that of the outer function, and that of its parents. This behavior is called lexical scoping.

Creation Phase: Setting The Value of The "this" Keyword

  • The next and final stage after scoping in the creation phase of an Execution Context is setting the value of the this keyword.

  • The JavaScript this keyword refers to the scope where an Execution Context belongs.

  • Once the scope chain is created, the value of 'this' is initialized by the JS engine.

  • "this" in The Global Context
  • In the GEC (outside of any function and object), this refers to the global object โ€” which is the window object.

  • Thus, function declarations and variables initialized with the var keyword get assigned as properties and methods to the global object โ€“ window object.

  • This means that declaring variables and functions outside of any function, like this:

var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}

Is exactly the same as:

window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
  • Functions and variables in the GEC get attached as methods and properties to the window object. That's why the snippet below will return true.

Conclusion:-

  • JavaScript's Execution Context is the basis for understanding many other fundamental concepts correctly.

  • The Execution Context (GEC and FEC), and the call stack are the processes carried out under the hood by the JS engine that let our code run.

  • Hope now you have a better understanding in which order your functions/code run and how JavaScript Engine treats them.

HAPPY Learning!!!๐Ÿ’ซ

Did you find this article valuable?

Support syed by becoming a sponsor. Any amount is appreciated!

ย