0 to 1- How JavaScript works under the hood
Tags: javascript, executioncontext, scope, webdev
Published: 2022-07-18 14:18:00

Many developers have been coding in JavaScript to carry out its legacy since [**Brendan Eich**](https://en.wikipedia.org/wiki/Brendan_Eich) developed JavaScript back in **1995**. If someone actually wants to learn JavaScript you need to understand JavaScript. You need to know the history of JavaScript, what problem it actually solves, and how JavaScript works behind the scene. This background info will help you out when you will be coding and when you are learning some new features.

In this article we will learn little **history** of JavaScript, how JavaScript works behind the scenes? What is the **Runtime environment**? What role does the **JavaScript engine** play in code execution? What the heck is **Execution context**? What is Scope, **TDZ**, and a lot more?

You ready 😉

## JavaScript History
First of let's discuss the need for JavaScript, so you can have some idea of why are you using JS and what was its purpose.

In the early days of the web (yeah, stone Age 😉), there were ways to create web pages(HTML was released in 1993), but there was no effective way to manipulate them. As we can these days with [DOM](https://medium.com/r/?url=https%3A%2F%2Fwww.w3.org%2FTR%2FWD-DOM%2Fintroduction.html%23%3A~%3Atext%3DThe%2520Document%2520Object%2520Model%2520%28DOM%2Cdocument%2520is%2520accessed%2520and%2520manipulated.) (Document Object Model - will be discussed later).  So those static pages were usually non-interactive. This was the major reason some language needed to be developed to give them life. 

Back in **1995**, [Brendan Eich](https://en.wikipedia.org/wiki/Brendan_Eich) stepped forward and developed the first version of JavaScript in mere 10 Days, it's not a typo I really meant 10 Days. It was then called **LiveScript**(cool name, but I like JavaScript more 😉). At that time JavaScript was like alien technology and was adopted quickly. The community kept expanding, it got better and better, and of course, JavaScript we use is a monster compared to those days.

At first, It was developed for **Netscape 2** and became the ECMA-262 standard in 1997. In **1997**, ECMAScript 1 was released and was supported in Internet Explorer 4 for the first time. Then in 1998, ECMAScript 2 came out, and ECMAScript 3 in 1999. This fourth edition of the language was a bit delayed and was released in 2008 but could not make it to market. The fifth major edition, **ECMAScript 5** was released in 2009. This version was used for a while and the latest version **ECMAScript 6** was released back in **2015**, which is now widely supported in all major browsers with and exception the of Internet Explorer. [Here](https://www.w3schools.com/js/js_history.asp) you can learn more about the history of your favorite language.

Here ECMAscript is

>ECMAScript is a JavaScript standard meant to ensure the interoperability of web pages across different web browsers. It is standardized by Ecma International according to the document ECMA-262. Bascially it standardizes what JavaScript code dos what, so JavaScript behaves the same way in every Browser.

You cannot possibly learn the language if you do not know how that Language works under the hood. Let's first understand a few important concepts we will be using a lot in this article.

## JavaScript in plain English
* JavaScript is an **interpreted language**, which means, like Java(no similarity with JavaScript except name ), it does not require us to compile it before sending it to Browser to be executed, the interpreter can take raw JS source code and execute it for us.

* JavaScript is **single-threaded** and **synchronous** in nature. This means it creates and executes all the tasks with a single execution thread. Tasks are **queued** one after another and the next task needs to sit and wait until the active task is completed.  There are still ways to run JS code **asynchronously**, which we will discuss further in this article.

* JavaScript is **non-blocking** programming or scripting language which does not block upcoming tasks if a program is taking so long, with the help of **Web APIs**, Callback queue, and event loop. For now, you might find this non-blocking statement contradictory to the above single-threaded statement. But we will discuss all these concepts in great detail in a while. You just need to be with me for the next few minutes.

* JavaScript is a **dynamically-typed** language, which means `var` can store any data type, like int, string, or object, unlike other statically typed languages like C, and C++ in which we have to explicitly specify variable type `datatype variable_name`.

## The Runtime Environment
The Runtime Environment is a special environment that provides our code access to built-in libraries, APIs, and objects to our program so it can interact with the outside world and get executed to full fill its noble purpose.

Runtime Environment is basically a factory where raw JavaScript code gets loaded and with a mixture of **Web APIs**, **libraries**, and **objects** it gets executed. Hopefully, this gives you some sense of the runtime environment. If you still have some doubts, do not worry we will be discussing components of the runtime environment and their part in JS execution in a short while. You just need to hang tight with me, and you will have a very clear picture of JS at the end of this guide.

In the context of a web **browser**, the runtime environment consists of following components:
* JavaScript Engine
 *  The Callstack or Execution Stack
 *  The Heap
* Web Apis (like fetch, setTimeout, DOM, File API)
* The Callback queue
* The Event Loop

Runtime environment depends on the context, in which you are running JavaScript code. The runtime environment might look a bit different depending upon the context. For instance in NodeJs environment JavaScript code has no access to Web APIs because they are a feature of web browsers. Basic features will be the same or similar though in case of any context.

A modern browser is a very complicated piece of software with tens of millions of line lines of code. So it is split into many modules which handle different logic. 

Two of the most important parts of a web browser are the JavaScript engine and a rendering engine.

### Rendering Engine
The rendering engine paints content on the screen. [Blink](https://www.chromium.org/blink/) is a rendering engine that is responsible for the entire rendering pipeline including [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction#:~:text=The%20Document%20Object%20Model%20(DOM)%20is%20a%20programming%20interface%20for,can%20interact%20with%20the%20page.) trees, styles, events, and V8 integration. It parses the DOM trees, resolves styles, and determines the visual geometry of elements on the screen.

### JavaScript Engine
The purpose of the JavaScript engine is to **translate** source code that developers write into **machine code** (binary) that processor can understand. So this is the place or factory you can say, where raw JavaScript gets downloaded, parsed, and transpiled into Machine code that can be understood by Processor.

JavaScript engine compiles and executes raw JavaScript source code into native machine code. So JavaScript engine is the place where JS source code is downloaded, parsed, interpreted, and executed at the end in form of Binary code. Every major Brower vendor has developed its own JavaScript engine, which basically works the same way. Like Chrome has [V8](https://en.wikipedia.org/wiki/V8_engine), Safari has [JavaScriptCore](https://trac.webkit.org/wiki/JavaScriptCore#:~:text=JavaScriptCore%20is%20the%20built%2Din,SquirrelFish%20and%20%E2%80%8BSquirrelFish%20Extreme.), and Firefox uses [SpiderMonkey](https://spidermonkey.dev/).

We will be focusing on the V8 engine in this article. Read what is V8 Engine from Google's words;

> V8 is Google's open-source high-performance JavaScript and WebAssembly engine, written in C++. It is used in Chrome and in [Node.js](https://nodejs.org/), among others. It implements ECMAScript and WebAssembly, and runs on Windows 7 or later, macOS 10.12+, and Linux systems that use x64, IA-32, ARM, or MIPS processors. V8 can run standalone or can be embedded into any C++ application.


#### Working of JavaScript Engine(V8)
The first version of V8 was released and used by the Google Chrome team in 2010 when they had some problems displaying Google Maps. Later on, they improved it over time and released another version of V8 in 2017, which is being used by Chrome browser these days.

The current version was built on this model;

![V8 JavaScript engine model](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tg929o4d2azb79jwtg52.png)

_[Image copied from [this](https://medium.com/jspoint/how-javascript-works-in-browser-and-node-ab7d0d09ac2f) awesome article by [Uday Hiwarale](https://thatisuday.medium.com/)]_

Let's break it down;

V8 engine downloads JS source code and passes it to **Baseline Compiler** which process and compiles code to lightweight [ByteCode](https://www.mirkosertic.de/blog/2017/06/compiling-bytecode-to-javascript/).

This bytecode gets passed to an **interpreter** which is basically an **IntelliSense algorithm** that knows what JS code dos what. It interprets the bytecode to CPU understandable [binary code](https://en.wikipedia.org/wiki/Binary_code).

At the very same time, Bytecode gets passed to the **Optimization compiler** which optimizes this ByteCode in the background while the application is running. It produces a very **optimized binary code**, which is eventually replaced with the code in the application, thus giving massive performance and boost.

This is the final model of the V8 engine. But this was not always like this. After many updates and remodeling, this very optimized version of the engine came into existence.

This is the basic functioning model of Chrome JavaScript Engine(V8). Other browser vendors use different JavaScript engines. But they function pretty much a similar way.

#### How JavaScript code works in the runtime environment
Unlike other programming languages, JavaScript is single-threaded in runtime, in plain English means it can run only one piece of code at a time. Code runs sequentially, so when one process is taking longer to run, it blocks the rest of the code after that waiting to be executed. Hence sometimes you might see, a Page Unresponsive alert. That usually occurs when some infinite loop of code is encountered in runtime. And it keeps running until all the CPU resources are consumed.

Consider this eternal loop;

![Eternal while loop](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/00huse14tehemooujvnj.png)

Here is what happens when this program is opened in Browser, it uses a single JavaScript execution thread, which is responsible for handling everything on the web page, like scrolling, events handling and fetching data from the server.

When this kind of infinite loop or huge JavaScript program is encountered, the execution of code gets blocked after it. Because JavaScript is single-threaded in nature and runs one piece at a time. Thus infinite loops keep running again and again until the system is out of resources. And we have to see the "Page Unresponsive" dialog.

![Page unresponsive dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4lbbge3rxu9irl06d3jj.png)

Thanks to modern browsers they use separate JavaScript execution threads for different tabs, otherwise, our browser would have been frozen if such a heavy program or infinite loop was encountered in one tab on one page. Modern web browsers usually use separate execution threads for different tabs or a single execution thread for one domain (same website on multiple tabs). Chrome uses a one-process-per-site policy so, if multiple domains were open in different tabs, all of them will stop working. Other domains (websites) tabs will keep working fine.

Let's discuss the JavaScript engine in detail. JavaScript engine consists of mainly two components; The **Callstack** and the **Heap**.

##### The Heap
The heap is the unstructured memory storage where variables and objects get stored during program execution. Then the heap, also known as the "memory heap" gets cleaned during garbage collection. I will not talk about it in detail, you can check out this awesome [article](https://levelup.gitconnected.com/understanding-call-stack-and-heap-memory-in-js-e34bf8d3c3a4).

##### The Callstack or Execution Stack
We are interested in the call stack, which is basically a LIFO (first in, last out) data storage where current executing contexts are stored while the program is running. We will discuss what **Execution Context** is in detail in a while. Each entry in the call stack is called a **Stack frame**. A stack frame contains information about the Execution Context, like its argument object, return address, local variables, etc.

### What is an Execution context?
JavaScript engine creates a special environment for the execution of JavaScript code, which contains the code that is currently running and everything that aids in its execution. This special environment is called the Execution context.

During the Execution context runtime, specific code gets parsed by a parser, variables and declarations get stored in memory(**VO**), and executable bytecode gets generated which is then converted to binary code, which gets executed.

Two kinds of execution contexts are created during runtime; 
- Global Execution Context(GEC)
- Functional Execution Context(FEC)

#### Global Execution Context(GEC)
When the JS engine receives some script file, a default Global execution context is created to handle the code at the root of that file, everything which is outside of any function.

This is the main/default execution context, that encapsulates all of the functional execution contexts.

There is only one GEC for any script file.

#### Functional Execution Context(FEC)
When the Global execution context encounters a function invocation, a different kind of execution context, very specific to that function gets created which handles all the logic inside that function.

As there are usually multiple functions inside any script (JavaScript file), every function gets executed in its very own execution context, and there can be multiple Functional Execution Contexts in a single program.

### How Execution Context is created?
As we already know that execution context has two major tasks, it prepares the script and then executes it. So we will try to understand the execution context in two phases;

- Creation Phase
- Execution Phase

#### Creation Phase
The creation phase of any execution context completes in three main steps.

- Creation of Variable Object
- Creation of the scope chain
- Assignment of `this` value

##### Creation Phase: Creation of Variable Object(VO)
For GEC a variable object is created which is basically a memory container, which stores properties for all variables and function declarations and stores references to them. When a variable is encountered in a global execution context property is added to the Variable Object and is initialized(in case defined with `var`) with the default value `undefined`.

When a function declaration is encountered, a property is added to the Variable Object, and a reference to that function is stored as a value.

This means before even the start of execution of code, variables and function declarations are available to use. Due to **hoisting**. We will discuss hoisting in great detail in a while.

In case of, **FEC** (functional execution context) doesn't create a VO but an array-like object called the **argument object**. All the arguments received by a function are stored in this array-like object.

#### Hoisting in JavaScript
JavaScript moves all the variables, function declarations, and class declarations to the top of their scope. This process is called hoisting in JavaScript.

In plain English, Prior to the execution of code, JavaScript stores all the variables, functions, and class declarations in the memory container, called Variable Object at the top of the scope, this process is known as Hoisting in JavaScript. Basically hoisting is the reason we can access **functions** and **variables** even before they are declared.

##### Function hoisting
Some JavaScript developers choose to define all of their functions at the top of the script and later call them at the end. The code below will still work fine due to hoisting, although we are calling the function before it was declared.


![Function hoisting](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ta3ukhg3mczjs90s992.png)

##### Variable Hoisting
Variables declarations are also hoisted. Variables declared with the var keyword are hoisted and initialized with a default value undefined. Mean if you will try to access a variable declared with `var`, you will not get an error but the value will be `undefined`.

If you declare a variable with a `let` or `const` keyword, their declaration is hoisted but not initialized with a default `undefined` value. That's why you will get an `uncaught ReferenceError`, when we try to access it before the declaration.


![Variable hoisting](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/736m24fazbhkdogsdo2q.png)

Here one thing is really important to discuss. You might be asked in an interview about this.

Starting from the top of the scope, until the complete initialization of a variable, that variable is said to be in **Temporal Dead Zone(TDZ)**. You should always try to access variables outside of its TDZ. If you try to access the variable from inside its TDZ, you will get ReferenceError. Here the question arises of where TDZ starts, and where it ends.

See the code below, you will know Temporal Dead Zone starts at the start of the code block(top of scope) and ends at initialization. Variables declared with `let` and `const` follow the same pattern.


![Temporal Dead Zone in case of let and const](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fhe78v6eudx0obukvfs.png)

In the case of variables declared with `var` the scenario is a bit different. And a guilty guy is hoisting. As we already know variables declared `var` are hoisted and initialized at the same time with a default value `undefined`. And we also know **TDZ** ends when a variable has been assigned a value. 

This is the reason `var` behaves a little differently compared to `let` and `const`. See this `code`;

![Temporal Dead Zone in case of var](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/piz9ejmb2tf0jkp38eph.png)

Hopefully, TDZ is all clear to you. Let's get back to hoisting.
There is one strict rule of hoisting, that hoisting only works for statements, not expressions. Have a look at this code;


![Hoisting rule only statements](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4z627t0l2gav17b4cg5s.png)

This is because we are assigning a function expression to a variable as a value. As we all know variables declared with let keyword are hoisted, but throw `ReferenceError` if called within Temporal Dead Zone. This is because their value is not initialized during hoisting and TDZ only ends after the complete initialization of the variable.

**Quiz Time**: Here is a small question for you? What would be the output if we used var instead of letting in the above code example. Can you guess whether any error will be thrown or function output will be logged to the console?

I am sure you guessed it right. The error will be thrown in this case stating something like myFunc is not a function, because at this stage value of the `myFunc` variable will be `undefined` due to Hoisting. So calling `undefined()` will throw an error.

##### Creation Phase: Creation of Scope chain
The scope is a mechanism in JavaScript which determines which piece of code is accessible from where. When a variable, function, or class is declared in a script, it has some address and some boundaries. Beyond those boundaries, it is **inaccessible**. The scope does answer many questions like from where code can be accessed? and from where it can not be? 

First of all, when the script is loaded in the engine, **global scope** is created, which basically holds everything which is not inside any function. All the functions and their inner functions can access this global scope.

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**.

Whenever a variable or function is called somewhere, the engine starts looking for an inside the local scope, where it was called. If not found, it looks for parent scopes (Lexical Scoping) one by one, from inner(local) to outermost (global scope). If the variable was not found in local and all the parent scopes including the global root scope, then the engine throws an error.

Every function execution context creates its scope which determines what variables and functions are accessible where. There are a few cases that we need to discuss to completely understand scoping.

**Case 1**: Variables declared inside a function can be accessed from anywhere inside that function, except for **Temporal Dead Zone**.

**Case 2**: Function declared inside a function has access to everything of its parent function and parent's parent function up to the global scope. This is called Lexical Scoping. This concept gave rise to something called **closures** in JavaScript.

When a function inside another function is called outside of its context, means outside of the parent function in which it was declared but it still has access to variables of the parent function even after the parent function has finished execution, this associative phenomenon is called **closures**. This is a very important concept and you definitely should check it out [here](https://www.freecodecamp.org/news/closures-in-javascript/).

Parent function has no access to anything declared inside of its child functions. The scope is like a one-way mirror, which means you can look outside but now one can look inside.


![Scope illustration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ltwit2vvff3fkner2qbs.png)

_[Image copied from [this](https://www.freecodecamp.org/news/execution-context-how-javascript-works-behind-the-scenes/) awesome article by [Victor Ikechukwu](https://www.freecodecamp.org/news/author/victor-ikechukwu/) at [freeCodeCamp](https://www.freecodecamp.org/)]_

As you can see in this image, the function `second` has access to all scopes including its own `local` scope, the scope of function `first`, and the `global` scope. But function first has only access to its local scope and the global scope. You can see it has no access to the scope of function `second`.

The second step of the creation of the Execution context completes here.

Till now Variable object has been created, scope chain is in place. Let's discuss the third and final step.

##### Creation phase: Setting the value of `this`

The next and final step in the creation of execution context is setting the value of `this`. this is a special keyword in JavaScript which refers to the scope of the environment where the Execution context belongs.

Value of `this` is different, depending on the context it is being used. Have a look at these cases;

**Case 1**: In Global Execution Context, `this` refers to the global window object in the case of browsers. Try logging "this" to the console inside GEC and you will see a `window` object. Here is one interesting thing to notice. When you define a variable or function inside GEC, they are saved as a property of the window object. This means these 2 statements are equivalent;


![this in GEC comparison](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ubvxrltxjj1o5g3n0xj.png)

And this will log true to the console;

![this in GEC comparison 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4nkl3cc36usojmhe273t.png)

**Case 2**: Inside FEC, a new `this` object is not created, but instead, it refers to the context it belongs to. Like, in this case, `this` refers to the global window object. As this function is declared in GEC, this would refer to the global `window` object.

![this in FEC](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydwa1zmdvtz75ewkbi5x.png)

**Case 3**: In the case of objects, using `this` inside the methods does not refer to the global object, but the object itself. Look at this example;

![this inside object methods](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/661inhtnzcmntwiesc49.png)

**Case 4**: Inside constructor functions, `this` refers to the newly created object, when called with `new` keyword like this;

![this inside constructor functions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abh60vpsstq4jqmjpn14.png)

With this, the creation phase of Execution Context has been completed. Till now, everything has been stored in VO, the scope chain is created and the value of this is in place.

#### Execution phase
Right after the creation of the execution context. JavaScript engine starts the execution of created context. But Variable Object currently contains all the declarations of that specific execution context but their value is undefined. And you already know we cannot work with `undefined`. So JavaScript engine again looks through VO once again and feeds their original values. After this code gets parsed by the parser engine, gets transpiled into lightweight bytecode, which is then converted to binary code(01), which then gets executed.

##### JavaScript Callstack(in terms of execution context)

First of all, the script is loaded in the browser, JavaScript engine creates the Global Execution Context. This GEC is responsible for handling all the code that is not inside of any function.

Initially, this GEC is the active execution context. When some function is encountered in this GEC, and new Functional Execution Context is created for the execution of that function. That FEC holds all the information about the execution of that function and everything that aids in its execution. This newly created execution context is placed right above the GEC. This process is repeated for every function call and FEC is added and piled up in the so-called **Callstack**.

Execution context on the top is executed first, and once that context is executed (something returned), it is popped out of the stack. The very next context becomes an active one and its execution starts. This process is repeated until there is the last GEC left in the stack. It is executed at the end and the script is said to be executed at this point.

##### Conclusion
et's sum up all of this by an example. We try to recall everything we have learned so far in this article.

Consider this program inside the script file;

![Execution stack conclusion img 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bcs7bjvee5t2lqy3hhvo.png)

First of all this `.js` file gets loaded in the browser, and passed to the JavaScript engine for execution. The engine creates a Global Execution Context for this file which handles the execution of the root of this script file, everything that is not inside a function. This GEC is placed at the bottom(or top) of the `Execution Stack`. Global Execution Context is created during two phases; the creation phase, and the execution phase.

Variable `name="Victor"` is stored in the Variable Object (**VO**) of GEC and initialized with the default value `undefined` (**hoisting**).

Then for all these functions `first`, `second` and `third`, a property is added to VO of GEC, and reference to these functions is stored as value. Hoisting you know 😉.
 
After setting the VO of GEC, the **scope chain** is created, and value is `this` set (`window`).

Now starts execution. But the value of `name` variable is still `undefined` in the VO. And we cannot work with undefined, Right? So once again JS engine looks through VO and feeds the original value of `name` variable, which is `Victor`. Now we are good to proceed further in our program.

![Execution Stack Visual](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zvwvj7j5r79leqqyo3u.png)

First of all, the function `first` gets invoked. JS engine creates a Functional Execution Context to handle its execution. This FEC is placed on top of the Global Execution Context, forming a **Callstack** or **Execution Stack**. For the period of time, this FEC is the active one, as we already know Execution Context on the top in Callstack is active. Variable `a = "Hi!"` gets stored in the FEC, not GEC.

![Execution Stack Visual phase 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e0o90uy1zywedujfux5s.png)

In the next statement, function `first` invokes function `second`. Another FEC is created and placed on top of the FEC of function `first`. Now this FEC is active. Variable `b="Hey!"` gets stored in the FEC.

![Execution Stack Visual phase 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ay7nsidf5s1zb2x8nupf.png)

Then function `second` invokes function `third`, similarly, FEC is created, and placed on the top of the Execution stack. Variable `c = "Hello!"` gets stored in the FEC.

So far Execution Stack looks like this;

![Execution Stack Visual phase 4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8861al5afhyy7btwudhc.png)

And logs `Hello Victor` to the console. But wait! Where does Victor come from? Variable `name` is not defined in the function `third`. You guessed it right, **Scope Chain**. The function `third` looks for name variable inside its local scope, but did not find it. Because of something called **Lexical Scoping**, it also has access to its parent scope, the Global scope. JavaScript engine looks for `name` in global scope and finds it.

When function `third` has completed all of its purposes, its FEC gets popped out of the Execution stack(Callstack).

![Execution Stack Visual phase 5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ay7nsidf5s1zb2x8nupf.png)

Then the very first FEC below it becomes active context and starts execution. Logs `Hey! Victor` to the console' and pops out of the Execution stack. Now the last FEC of this program becomes active, logs `Hi! Victor` to the console. After execution of all of the statements, it is destroyed and pops out of the Callstack.

![Execution Stack Visual phase 8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zvwvj7j5r79leqqyo3u.png)

We are again left with only GEC in the Execution stack. As well it has nothing left to execute it also pops out of the stack.

Hopefully, this example cleared up most of your doubts. We have discussed the first component of the JavaScript Runtime Environment so far. Hopefully, you find it helpful.

#### So far we have learned
* **A little history of JavaScript**

* **JavaScript Runtime**, which is basically a special environment provided by the browser or context we run our code in. This environment provides us with objects, APIs, and other components so our code can interact with the outside world and get executed.

* **Components of runtime environment**; like JavaScript engine, Web APIs, Callback queue, and Eventloop.

* **JavaScript engine**, which again consists of Callstack or Execution Stack and the Heap.

* **Execution Context**, which is basically a special environment for the execution of JavaScript code, contains the code that is currently running and everything that aids in its execution. This special environment is called the Execution context. 

* **Types of execution context**; like Global Execution Context(**GEC**) and Functional Execution Context(**FEC**).

* **The creation phase of Execution Context**, which completes in three phases; Creation of VO, Scope chain building, and the setting value of this.

* **The execution phase of Execution Context**, we learned how GEC is created once the script is loaded and how every function creates its own FEC. They keep stacking on one another unless they return something and get popped out of Stack.

* **Scoping and Temporal Dead Zone**, we learned how functions can access declarations from their parent scope via **Lexical Scoping**. We briefly discussed TDZ as well.

#### The drawback of JS **single-threaded** nature
As we all know JavaScript is single-threaded in nature, as it has only one heap and one stack. The next program has to sit and wait until the current program finishes execution, heap, and Callstack get cleared and the new program starts executing.

But what if, the currently executing task is taking so long, what if our current execution context is requesting some data from the server(slow server), definitely it would take some time. In this case, the Callstack queue will be **stuck** as JavaScript only executes one task at a time. All the execution contexts that are next to be executed will keep waiting until our current guilty Execution context is resolved. How we can handle this sort of behavior. How can we schedule some tasks, or park some expensive tasks so that we can keep our application going? How can we make our **synchronous** JavaScript **asynchronous**? 

This is where **Web APIs**, **Callback queue**, and **Eventloop** come to the rescue. My plan was to discuss all of these concepts in a single guide, but the length grew more than I expected.

#### What Next?
Now we are left with the other three components of JavaScript Runtime,

* Web APIs
* The Callback Queue
* The Eventloop

I will be dropping another guide like this on these left components. If you want to get notified of the next part, follow me 😉.

This was the first component of the JavaScript runtime, the Working of the JavaScript engine in the code execution. I have tried to simplify all the concepts so even absolute beginners can understand them. Hopefully, you were able to understand it, and found it helpful.

#### Credits and Motivations 
While writing this guide, I found really awesome articles you should also check. These articles helped me write this extensive guide.

* Really awesome article [How does JavaScript and JavaScript engine work in the browser and node?](https://medium.com/jspoint/how-javascript-works-in-browser-and-node-ab7d0d09ac2f) by [Uday Hiwarale](https://medium.com/@thatisuday).
* An extensive article on [JavaScript Execution Context](https://www.freecodecamp.org/news/execution-context-how-javascript-works-behind-the-scenes/) by [Victor Ikechukwu](
https://www.freecodecamp.org/news/author/victor-ikechukwu/).
* Elegant guide on [JavaScript Runtime Environment](https://medium.com/@gemma.croad/understanding-the-javascript-runtime-environment-4dd8f52f6fca#:~:text=What%20is%20the%20runtime%20environment,and%20make%20the%20code%20work.) by [Gemma Croad](https://medium.com/@gemma.croad).

#### Final Words

If you liked this guide and want to get notified of my next articles like this, please do follow me. If your friend is struggling with these concepts, do share this guide.

Till then, Stay safe, and try to keep others safe.

See you soon💓