DEV Community

Cover image for Mastering JavaScript 🧑‍💻: How the js engine works
Saverio683
Saverio683

Posted on • Updated on

Mastering JavaScript 🧑‍💻: How the js engine works

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

🔎 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

⚙️ 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())
Enter fullscreen mode Exit fullscreen mode

example

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")
Enter fullscreen mode Exit fullscreen mode

example 2

So in the end the final pattern will look like this:
JS Engine

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

Latest comments (4)

Collapse
 
peterkulko profile image
Peter Kulko

Thanks

Collapse
 
drsensor profile image
૮༼⚆︿⚆༽つ

You forgot explaining about the microtask

Collapse
 
posandu profile image
Posandu

The latest Edge uses chromium, that mean it uses the V8 JavaScript engine.

Collapse
 
saverio683 profile image
Saverio683

Thanks for letting me now that so I'll make the changes to the post