This blog? So original. AI ain’t got nothin’ on me. 😉 (just the title)
JavaScript, once a subject of mockery in terms of performance, now powers every dynamic web application and interactive experience with lightning-fast speed. This transformation wouldn’t be possible without its secret weapon: the Just-in-Time (JIT) compiler. But what exactly is a JIT compiler, and how does it make JavaScript sing?
Understanding the Stage: Interpreters vs. Compilers
In order to fully understand the JIT’s magic, we must understand the two fundamental approaches used for executing our code
One of the most debated question in the JavaScript world: Is Javascript an interpreted language or a compiled language? Let’s not confuse ourselves and keep it to the point, crisp, and clear with an in-depth explanation.
As we all know from the very beginning, computers don't understand programming languages like C, C++, Python, Java, JavaScript, etc. We call them high-level programming languages.
So our ultimate goal is to convert our source code from high-level languages to computer-understandable code called Machine Code. Compilers and interpreters help us do that.
Interpreters
An interpreter reads high-level source code line by line and translates it into an intermediate form called bytecode. This bytecode is closer to the language that the computer understands, but it isn’t machine code yet. The interpreter executes this bytecode line by line, converting it into machine code on-the-fly for the CPU to execute directly. This process enables the computer to understand and execute the instructions from the original source code.
Compilers
A compiler takes an entire source code file. It will scan it completely, then convert the entire source code into machine code, and voila, our code is ready for execution. Once compiled, the machine code allows the computer to swiftly execute the program without needing to re-translate the source code each time it runs.
Interpreters vs Compilers
Interpreters start fast when executing code, while compilers take longer initially due to the upfront compilation step. However, compilers ultimately run faster.
An error on a specific line will not be discovered by an interpreter until all lines above it have been executed. In contrast, a compiler catches errors on individual lines during the parsing phase before any execution begins.
Looping can be slow with interpreters compared to compilers because they don’t inherently optimize code. In contrast, compilers can recognize repeated code within loops and optimize it for faster execution.
Just-in-time compilers: the best of both worlds
Initially, when JavaScript was created, it was an interpreted language. But in the late 2000s, some engineers came up with the idea of combining both of them and creating something called a JIT (Just in Time Compilation).
Understanding JIT Compiler
The interpreter will take out the source code and start interpreting the code line by line. There is something called a profiler.
The profiler's main job is: When a program runs, the interpreter goes through the code line by line. Meanwhile, there’s this thing called a profiler that’s always watching how the code performs. Its main job is to pay close attention to how the code runs. When it notices that the code does the same things over and over, it sees a chance to make things faster or more efficient. So, it steps in, finds unoptimized code, and passes it to the compiler to perform optimizations and generate machine code, which eventually replaces its counterpart in the previously generated non-optimized code by the interpreter.
As the profiler and compiler constantly make changes to the bytecode, the JavaScript execution performance gradually improves.
So the answer to the main question, “Is JavaScript interpreted or compiled? Is that, basically, JavaScript can act as both an interpreted and compiled language. It completely depends on the JS engine that you have been using. Well, most modern browsers or JS engines use JIT compilation.
To conclude, JavaScript is primarily an interpreted language, executed by an interpreter within a runtime environment. However, modern JavaScript engines use a blend of interpretation and compilation techniques. They interpret code initially and then compile parts of it into machine code or bytecode, often employing Just-In-Time (JIT) compilation for improved runtime performance.