Javatpoint Logo
Javatpoint Logo

JavaScript Execution Context

The topic is very much 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, 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 a 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 functions, 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

Begin to discuss each one by one:

Global Execution Context

GEC / Global Execution Context is also called the base/default execution. Any JavaScript code which does not reside in any function will be present in the global execution context. The reason behind its name 'default execution context' where the code begins its execution when the file first loads in the 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, reference the Windows object to 'this' keyword.
  • Create a memory heap in order to store variables and function references.
  • Then it stores all the functions declarations in the memory heap area and the variables in the GEC with initial values as 'undefined'.

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 Code is that type of context which is created by the JavaScript engine when any function call 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. During the GEC code execution, a function call is initiated, and when found by the JS engine, it creates 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. At the bottom of the execution stack, GEC resides, and it is present by default in the stack. So, when beginning a JS code execution (i.e., during GEC execution), when any function is present in the code, and the JS engine searches it, it instantly creates a function execution context (FEC) for that function and pushes it on the top of the execution context stack. The particular execution context which is available at the top of the execution context stack will always get executed by the JS engine first. As soon as the execution of all the code is done, the JS engine pops out the function's execution context and then moves towards the next and so on. Generally, when the script loads in the browser, the first element will be the global execution context. But when a function execution is detected, the execution context is created and gets virtually placed on the top of the GEC. The process continues until the execution of the whole code gets completed.

In order to understand the working process of the execution stack, let's consider an example code given below:

It is an example code to understand its working.

Explanation:

  • Firstly, all the code is loaded into the browser.
  • After it, the JS engine pushes/inserts the GEC at the top of the execution stack.
    JavaScript Execution Context
  • As soon as the JS engine encounters the first function call, it set up a new FEC for it and adds it to the top of the current execution stack.
    JavaScript Execution Context
  • Then we can see that it is the invocation of the second function within the first function. Therefore JS engine setup a new FEC for the second function and insert it to the top of the stack.
    JavaScript Execution Context
  • When the second function is completed, the execution function is popped out of the stack, and controls move to the next execution context present in the stack, which is the first function execution context only.
    JavaScript Execution Context
  • When the first function gets executed completely, the execution stack of the first function popped out from the stack. Hence, the control reaches back to the GEC of the code.
    JavaScript Execution Context
  • At last, when the execution of the entire code gets completed, the JS engine removes the GEC from the current stack.

In this way, the execution of the execution stack is performed.

Creating an Execution Context

An execution context is created first, and then it is managed. The creation of the execution context is performed in two approaches:

Creation Phase

The creation phase is the one in which the JS engine invokes a function but does not begin its execution. In this phase, the JS engine begins its compilation phase and scans the particular function code for compiling it but does not execute the code. Creation of the Execution Context is the responsibility of the JavaScript engine, and it creates it by performing the following described tasks:

Task 1: Creation of the Activation object/Variable Object: One of the special object of JavaScript that is like a container that holds all the information of the function arguments, variables as well as inner functions declaration. With this, it does not have the dunder proto property.

Task 2: Creation of the scope chain: After completing task 1, the JS engine initializes the scope chain. A scope chain is a list that has all the variables objects within which the current function exists. A scope chain also has the variable object of the GEC and carries the current function variable object.

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

Let's try to understand the creation of the Activation object with the help of the below example:

Example Code 1

Now, the JS engine creates an executionContextObj for example code 1 after the invocation of test () and before executing its code. It can be seen in the below code:

The Activation object contains the argument object that further contains the details about the arguments of the function. It carries the property name for every function and variables that are declared within the current function. In our case, the Activation object, for example, code 1will be:

Explanation:

  • The JS engine has created the argument object, as you can see in the above code. Also, there exists a length property that contains the total number of arguments in the function. It is having only the property name and not its value.
  • After this, for each variable in the function whose value is initialized with 'undefined', the JS engine setups a property on the activation or variable object. These arguments are also variables in the function, so are also a property of the argument object.
  • If there is a situation where the variable is already present as the argument object property, then the JS engine moves on without taking any further action.
  • When the JS engine finds a function definition within the current function, by using the name of the function, it creates a new property. As discussed above, function definitions get stored in heap memory. The function name property points to its definition in the heap memory.
  • So, we can see in the above code that w is a variable. Therefore, it will get the value of 'undefined'. However, when a function with the same name is found, overriding will take place, and its value will point it to the definition of function w, which is stored in the heap memory. After it, the JS engine setup the scope chain and determine the value of 'this'.

So, in this way, the creation phase works.

Execution Phase

The execution phase is the next phase after finishing the creation phase. An execution phase is the one where the JS engines scan through the function in the code once again, i.e., one more time for updating the variable object with the values of the variables and then run the code. Let' see the execution stage or the complete code for the example which we have discussed above:

Example Code 2

Firstly, the above code gets loaded in the browser. After that, the JS engine begins its compilation phase in order to create the execution objects. In the compilation phase, the JS engine manages and handles the declarations only and does not care about the values.

Now, in the execution phase, the following steps will be performed as described per line:

  1. Variable x is assigned with 10, which makes the JS engine not to think of it as a function declaration or variable declaration and moves further, i.e., to the third line. In the third line, it does not do anything as it is not any declaration.
  2. Next, the JS engine setup a property with 'z' (variable name)in the GEC object because z is a variable name and also in global declaration scope and will initialize it with an 'undefined' value.
  3. Moving to the fifth line of the code, a function declaration is encountered by the JS engine. The JS engine will store the function definition in the heap memory and, after that, will set up a property that will point to that specific heap memory location. It does not matter what is stored in the function, it just points to its location.
  4. As we can see in the last line, it is not any declaration of the code. Hence, the JS engine will not perform any action.

So, in this way, the working of both the creation phase, as well as the execution phase, takes place.

GEC object after the creation phase stage

In the above explanation, we saw how the execution stack is created via the execution and creation phase for example code 2. However, we should take a deep understanding of the working of the GEC and FEC for the above-mentioned code only. Consider the below GEC object code for example code 2:

As you can see above, no code is left, the JS engine moves to the execution phase for scanning the function once more. The JS engine updates the value of the variable then execute the code in the following way as described below per line:

  • Firstly, the JS engine finds that no property is there having name x in the variable object, so it adds this property in the GEC and initializes its value as 10.
  • Next, the JS engine finds that a property with the name y in the variable object is present and thus updates its value to 20.
  • At last, the JS engine does not take any action because it is a function declaration.

Now, let's see the GEC object after the execution phase.

GEC object after Execution Phase

In our example code 2:

  • Now, as z () gets called again, the JS engine again enters the compilation phase. Thus, it scans the function for creating the execution context object of it.
  • The function z() has 'val' as its argument, so the JS engine will add 'val' in the argument object of the z() execution context object. Then it creates a property via the name 'val'.
  • Next, it checks and finds if p is a property in the activation object of the function or not. Hence, it found that there is no such property exists, so it will add p as property then initialize its value to 'undefined'.
  • Next, it is the duty of the JS engine to see if q is a property in the activation object of the function. Hence, it found that there is no such property exists, so it will add q as property then initialize its value to 'undefined'.
  • Then, the JS engine proceeds to the next line as x = 30 is not a declaration.
  • Then, the JS engine encounters a test () function declaration, and for it, it stores the function definition in the heap memory area. Then, it set up a property with the name 'test' that points to the location where function definition is stored. The JS engine does not focus on what is the value stored in it.

z execution object after the compilation phase

Below is the code for the FEC object after completing the compilation phase:

The code after the compilation phase of the example code 2 is performed as described below:

  • It is the test () function call and not a declaration because of which the JS engine will not do anything.
  • Now, the JS engine will proceed to the execution phase for executing the z () function by scanning it.
  • In the execution phase, the variables p and q get the 5 and 10 as their values.
  • Next, the JS engine finds that x is not a declaration and any property on z execution context object, so it moves to the GEC of the code via the scope chain and sees in the GEC any property with the name x exists or not. If not found, the JS engine will create a new property with the name x and will initialize it. In example code 2, the JS engine finds a property with the name x that already exists on the GEC object, so it updates its value to 30 from 10. One should note that the JS engine proceeds to the GEC in this case only, i.e., when it finds a variable in the execution phase which is not a property on the current execution context object
  • After it, the JS engine sets up a test property and then will point to its heap location.

Execution Context Object of z after the execution phase

In example code 2:

  • In example code 2, once again, the JS engine moves to the compilation phase for creating the execution context object for 'test'.
  • The test execution context object is having access to every function defined on z, on variables, and is also in the global scope using the scope chain.
  • In the same way, z has access to every variable and object in the global scope. However, it cannot access the test variables and objects.
  • The GEC of the code is not having any access to z or test variables or objects.

So, this is how the execution context is created and is defined.

Global Execution Context Vs. Function Execution Context

There are the following differences between the two:

Global Execution Context Function Execution Context
It creates a global scope. It creates an argument object.
It creates an object known as 'this.' It points to the Window object by default.
It set up memory space for the functions and variables that are globally defined. It set up memory space for functions and variables that are defined within the function only.
The GEC, while setting any function declaration in the memory, assigns a default value as 'undefined' to the variable declaration. The FEC, while setting any function declaration in the memory, assigns a default value as 'undefined' to the variable declaration. With this, it creates its own Execution Stack also.





Youtube For Videos Join Our Youtube Channel: Join Now

Help Others, Please Share

facebook twitter pinterest

Learn Latest Tutorials


Preparation


Trending Technologies


B.Tech / MCA