We're planting a tree for every job application! Click here to learn more

JavaScript under the hood

Isaac Godwin Udofia

21 Nov 2022

•

6 min read

JavaScript under the hood
  • Node.js

JavaScript was earlier meant to be used only within the web browsers but with the evolution of Node, JavaScript now lives outside too. And we know how to use it, where to use it & when to use it. But do we know what happens behind those scripts?

And if you know it, give yourself a high-five but you may still get something out of this article.

JavaScript is a high-level language, but a computer understands only 1’s and 0’s at the end. So how does a computer understand the code that we write? Getting a fundamental knowledge of any programming language you learn will make you write better code. And in this article, we have only one question to explore, How does JavaScript work?

Let’s get started.

The JavaScript Engine

This is the main character that we are gonna explore more and is responsible for making the computer understand what we write as a JS code. A JavaScript Engine is the one which takes in our code and converts it into a machine-readable language. It does more of a translator work, it simply translates our JS code to a language which a computer can understand. Without a JS Engine, the code you write is simply gibberish to a computer. And this is not only specific to JS, but every other programming language will also have an engine to make that gibberish meaningful to a computer.

And there are various JavaScript Engines that are available for use. You can refer this Wikipedia page for the list of available JS engines. And they are also called as ECMAScript engines due to a reason which you will find later in this article. From that list, you can see some of the popular ones which we use daily,

  • Chakra, Microsoft IE/Edge
  • SpiderMonkey
  • FireFox
  • V8, Chrome

And there are even more. So going on, we will look inside this engine to know how our JavaScript files are translated.

Inside the JavaScript Engine

Now we know that an engine is required, we might have a question,

Who creates an javascript engine?

The answer is, anyone can. It’s just another language which breaks down our code and translates it. And V8 is one of the most popular JavaScript Engines which is used by Chrome and NodeJs. It’s written in C++, a low-level language. And if everyone comes out to create an engine, it becomes totally messed up.

So, to keep an overwatch on these engines, a standard was created called ECMA which provides a specification on how to write an engine and all the features of JavaScript. This is why there are new features of JavaScript being implemented on ECMAScript 6, 7, 8, etc. And so the engines are also updated to support these new features. Hence we check the availability of an advanced JS feature in browsers during development.

We will take the V8 engine to explore things further but the fundamental concepts remain the same in all engines.

Okay, now let’s get more technical.

1_t90aAbr94kX-jIon-JfOSg.jpeg

This is what a JS Engine will look like inside. The code that we input will pass through the following stages,

  • Parser
  • AST
  • Interpreter produces ByteCode
  • Profiler
  • The compiler produces Optimized Code

Don’t worry if those terms scare you. It will all make sense within a few minutes.

So before we go over those stages, there is an important difference that we need to know about.

Interpreter VS Compiler

Generally, there are two ways of converting the code into a machine-readable language. And the concept that we are gonna talk about applies not only to JavaScript but also to most of the programming languages like Python, Java, etc.

An Interpreter reads the code line by line and executes it immediately. A Compiler reads on your entire code, does some optimization and then produces an optimized code. Okay. Let us go over one more time with an example.

function add(a, b) { return a+b } for(let i = 0; i < 1000; i++) { add(1 + 1) }

The above example just calls a function called add for 1000 times which adds two numbers and returns the sum.

If we give this file to an Interpreter, it reads on line by line and executes the function immediately till the loop is over. So it just translates the code into something which our computer can understand on the go. And if we give this file to a Compiler, it reads on the entire program, does some analysis of what we wanted to do and produces an optimized code in some other language which a machine can understand. It’s like taking X(our JS file) & producing Y(Optimized code that a machine can understand). And if we use an interpreter on Y(Optimized code), the result will be the same as it was before while interpreting X(JS Code).

And from the above image, byte code is just an intermediate code which still needs to be interpreted for the computer to process. But both the interpreter and compiler converts source code into machine code but the only difference is on how the conversion is done.

An Interpreter converts the source code line by line to equivalent Machine Code. A Compiler converts the entire source code to Machine Code at once.

By the time, you could have known about Babel, a JS compiler that takes in your modern JS code and compiles down to a browser-compatible JS Code(Older JS Version).

Pros and Cons of Interpreter & Compiler

An interpreter has the advantage of executing the code immediately without the need of any compilation. And this may seem helpful for running JS files in the browser since we don’t want to wait. But this gets slow down when there is more JS code to interpret. Remember our little code snippet where we called a function 1000 times. In that case, the output remains the same even though the function add was called 1000 times. These kinds of situations make an interpreter slow.

But a compiler can do some optimization in such cases by replacing the loop with a single number 2 (Because we added 1 + 1 every time) as it remains the same for all the 1000 iterations. The final code that a compiler gives out will be optimized and can be executed much faster. So, an interpreter can start executing the code immediately but it does no optimization. While a compiler takes time to compile the code but produces a more optimized translated code.

Okay, that’s enough about Interpreters and Compilers. Now let us get back to that main JS Engine Diagram.

So with the pros and cons of a compiler and interpreter in mind, what if we used the best of both? And this where JIT (Just In Time) Compiler comes in. It’s a combination of both the interpreter and the compiler and most of the browsers are now implementing this feature to be faster and efficient. And the V8 engine also uses this feature.

a1.jpeg

In this process,

A Parser is the one which identifies, analyzes and classifies various parts of our program such as whether is it a function? is it a variable? etc by looking on the various JavaScript Keywords. AST (Abstract Syntax Trees) then constructs a tree-like structure based on the classification from the parser. There’s an AST Explorer which you can check out to know how the tree is constructed.

The Tree is then given to the interpreter which then produces a ByteCode. And as we saw earlier, byte code is not the lowest level of code but it can be interpreted. At this stage, the browser with the help of the V8 engine does its work with the available byte code so that the user doesn’t need to wait.

On the same time, the profiler looks for any code optimizations and then passes the input to the compiler.

The compiler produces an optimized code while the byte code is used temporarily to render things on the browser. And as soon as the optimized code is produced by the compiler, the temporary byte code is completely replaced by this new optimized code.

And hence in this way, we could use the best of both the interpreter and the compiler. The interpreter executes the code while the profiler looks for optimization and the compiler creates an optimized code. Then the byte code is replaced by the optimized code which will be a lower-level code such as a Machine Code.

This simply means that the performance is going to gradually improve at the same time not blocking any execution time.

Note on Byte Code

As Machine Code, a byte code cannot be understood by all the computers. It still needs a middleware like Virtual Machine or an Engine like Javascript V8 to interpret it to a machine-readable language. And that’s why our browsers can execute this byte code from the interpreter during those above said 5 stages with the help of JavaScript Engines.

So, here comes another question,

Is JavaScript an interpreted language?

Yes, but not completely a yes. It was once during the early stages of JavaScript when Brendan Eich first created the JavaScript Engine ‘SpiderMonkey’. And the engine had an interpreter to tell the browser what to do. But now, we just don’t have interpreters alone, we have compilers. And our code is not only interpreted but also compiled for optimization. So technically, it all depends on the implementation.

That’s it for the overall big picture of how JavaScript works. And it’s totally fine not to know this for learning JavaScript. You can, of course, write code without even knowing how JavaScript works. But if we know behind the scenes, we can write better code. It’s that simple. And I will follow up with how to write optimized code on my next article. Until then, Bye!

Did you like this article?

Isaac Godwin Udofia

See other articles by Isaac

Related jobs

See all

Title

The company

  • Remote

Title

The company

  • Remote

Title

The company

  • Remote

Title

The company

  • Remote

Related articles

JavaScript Functional Style Made Simple

JavaScript Functional Style Made Simple

Daniel Boros

•

12 Sep 2021

JavaScript Functional Style Made Simple

JavaScript Functional Style Made Simple

Daniel Boros

•

12 Sep 2021

WorksHub

CareersCompaniesSitemapFunctional WorksBlockchain WorksJavaScript WorksAI WorksGolang WorksJava WorksPython WorksRemote Works
hello@works-hub.com

Ground Floor, Verse Building, 18 Brunswick Place, London, N1 6DZ

108 E 16th Street, New York, NY 10003

Subscribe to our newsletter

Join over 111,000 others and get access to exclusive content, job opportunities and more!

© 2024 WorksHub

Privacy PolicyDeveloped by WorksHub