Execution Model of JavaScript
Tags: javascript, intepreted, compiled
Published: 2021-09-26 09:53:18

JS has been often classified as a scripting interpreted language. However, the truth to this matter is that there are more than one ways of interpreting (pun intended & left to your interpretation).

## Models of Execution

The usual method that we think of, when the phrase _interpreted language_ is mentioned, is the line by line execution of the source code. In this processing model, each line is transformed into machine code, the transformed line of code is executed and only after that does the processing model continue to the next line.

![interpreted execution model](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z6nt4eemvogzlko2pisj.png)

There is another processing model called _compilation_ where the entire source code is taken and transformed at once into machine instructions and these instructions are saved into another file. Once the compiled machine instructions file is created, executing this file will run the output of original code.

![compiled execution model](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l7ijg2bixh27zkc4z3d9.png)



## Is JS interpreted? A prologue to JS execution

The question still remains that whether JS employs this method of line by line conversion of code, followed by execution, we commonly refer to as 'interpretation'? Well, the answer is little more subtle than a yes or a no answer. JavaScript engines have amalgamated both of these above mentioned processing models into how they execute JS. Even though, these engines don't generate a compiled machine instruction file, JS is still compiled before it starts executing. I know. I know. That was a lot to take in just one sentence but just give this idea [five minutes](https://signalvnoise.com/posts/3124-give-it-five-minutes) and the pieces to the puzzle of JS's execution mechanism will suddenly start to fit. Keeping this idea in mind that JS first compiles the entire code, let's continue ahead.

The behavior that JS compiles it's code first, is noticeable through something as plain as 'syntax errors' and 'hoisting'.

### Making a Syntactical Error

```js
console.log("Hello World"); // this won't be printed
var wrongJS => 'this will throw an error';
```

If JS was interpreted, transformed, and executed line by line without moving to the next line before completing this process, the first line would've printed "Hello World" to the console because the error lies on line 2. But, it doesn't get executed line by line without getting compiled first and it didn't print to the console because of the syntax error. This is one such example portraying that there are certain elements of compilation at play here.

### Hoisting a Function Declaration

```js
print_hello();

function print_hello(){
  console.log("Hello");
}
```

Again, if JS was interpreted line by line, it couldn't have looked ahead on line 3 without executing line 1. That would mean that JS didn't know what `print_hello()` is on line 1 and it should've rightfully thrown a reference error. But, it didn't throw an error and instead, it successfully executed the function and printed to the console. 

These examples clearly poke some holes in the theory that JS is a strictly interpreted language. So, does that mean JS is entirely a compiled language? Hold your horses. As I said, JS engines implement a mixture of both these methods. 

## Conclusion

From the evidence of the above give peculiar cases, it should suffice to say that JS engines have a compiler which compiles the code into a byte code and this byte code is then fed into an interpreter which generates a machine code to be executed. This is a high level explanation of how JS code gets run without getting into the details of the baseline compilers, JIT compilers, interpreters and what not.

Fun fact: As JS engines don't have typical compilation step of being compiled ahead of time, the compiled code isn't always optimized because they don't always have as much time to optimize it. Hence, they use optimizing compilers to optimize the repeated pieces of code during the execution by keeping a track of executed code and the data that's used for execution.

Hopefully, the idea about how JS engines execute code has started to make more sense. We'll explore this concept more in future post of scoping mechanisms.