Mastering JavaScript 🧑‍💻: How the js engine works
Tags: javascript, webdev, beginners, programming
Published: 2022-07-29 22:02:00

Hello everyone 👋, I hope you are doing well.

With this post I plan to start a new section called *Mastering JavaScript*, where I will expound on my knowledge of the programming language learned over time and I hope you find this content useful. 

With that said, let's get started!

#📘 INTRODUCTION

JavaScript is an **interpreted** programming language and was born **client-side**. 
* **Interpreted** language means that the code, written by the programmer, is "read" line by line by an interpreter that simultaneously converts it into *binary code*, understandable by the CPU so that it can be executed.
* It is called **client-side** because the environment in which it runs is the browser, which is located in client devices such as smartphones, PCs, etc... 

*(Since 2009, JavaScript has also become server-side thanks to Node.js, but I will talk about that in a future post, here I would like to focus on the browser-side)*

So the element that is responsible for managing the js execution lifecycle is the *JavaScript engine*, located inside the browser.

![JS engine](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2gzwqyhsscvewx2eucud.png)

#🔎 HOW MANY TYPES OF ENGINES ARE THERE?

Nowadays there are several engines implemented by various browsers that share many features. One of the first was **SpiderMonkey** born in 1995 for the Netscape browser and is currently used by Mozilla Firefox, Chrome has **V8** which is one of the most powerful, Safari uses **Nitro** and so on and so for...


![Different Engines](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7xk014ugy52ahcrdi0dx.jpg)

#⚙️ HOW THE JS ENGINE WORKS

Now that we know what a browser engine is, we can get more specific and find out how it works.

###THE JS RUNTIME ENVIROMENT

The runtime consists of the **call stack** and the **memory heap**:
* The **stack** is a data structure that stores instructions to be executed and when they are executed they will be removed. The first thing that is added to the call stack is the *global execution context* (or GEC). The GEC consists of the global object, which contains all the JavaScript built-ins and global variables written by the programmer (e.g. for the browser it's the *Window* object).
Then other stacks will be added from the functions created by the developer.
So, when the code execution is finished, the last element to be removed from the stack will be the GEC.
* In the **memory heap**, on the other hand, variables are stored dynamically: variables are allocated automatically when a function is called, and they are "deleted" automatically when the function exits. This is done by the garbage collector.

Here is an example:

```
function one() {
  return 1
}

function two() {
  return one() + 1
}

function three() {
  return two() + 1
}

console.log(three())
```

![example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pow3rb3hzo7zr5lrvghv.gif)

Where *main()* is the GEC.

As we know, JavaScript allows it to be executed *asynchronously* through special features contained in **Web APIs**.
In fact, it is within them that asynchronous functions are executed and not within the call stack (since we only have one).

After that, their result of the API (the function in it) is put into the **Callback Queue**, waiting for the call stack to clear. 
The engine is able to tell that the stack is empty and therefore needs to move the data from the Callback Queue thanks to the **Event Loop**, which is nothing more than a listener that continuously monitors the stack.

Here's an example:

```
console.log("start")

setTimeout(function() {
  console.log("1 sec delay")
}, 1000)

console.log("end")
```

![example 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytasjjhgcj1dnzm8yr53.gif)

So in the end the final pattern will look like this:
![JS Engine](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnfe4hzuajqv2fmcu80p.png)

###THE JIT COMPILER

As I said before, js is an interpreted language. 
But nowadays browsers like V8 have implemented **just-in-time** or **JIT compilers**, that is, they combine the features of both *interpreter* and *compiler* to achieve better performance.

The interpreter as a pro takes very less time to analyze the source code but slowdowns can occur during code execution ( because it interprets the bytecode whenever a method is invoked, this would not be optimal e.g., in the presence of loops). 
On the other hand, the compiler scans the entire program and translates the whole of it into machine code at once, thus achieving greater stability and the overall time to execute the process is much slower.

The JIT compiler manages to optimize time by interpreting the code, and assigns to the compiler only that which is reusable (such as methods) by compiling it into native machine language "just in time" to run.

#🌐 RESOURCES

[JavaScript Engine, Call Stack, Callback Queue, Web API and Event Loop](https://simonzhlx.github.io/js-engine/)
*(I got the gifs and examples from the link above)*

Thank you for reading 🙂! I hope you enjoyed the post and that it may have been helpful to you, if so please leave a like. 
You can follow me to stay updated on my new posts.