JavaScript Compiler theory and how it relates to scope
Geo Mukkath
Posted on October 28, 2022
*JavaScript is a COMPILED language. *
This will throw a lot of interviewers off their seats but that's a fact.
JavaScript compiles code and executes it on the spot, giving users the illusion that it's an interpreted language.
In the following lines I will give you a glimpse of what happens behind the curtains but more importantly I will be going deep on how all of this is tied to scope.
There are 3 concepts which you need to know before we proceed further.
1.Tokenizing
Think of tokenizing as breaking down each and every element in a piece of code.
For eg. let a = 5;
can be broken into various elements namely
let, a, =, 5 and ;
Each element here is a 'token'.
Simple ? Ain't it ?
Onto the next step.
2. Parsing
During Parsing the tokens are parsed into a tree like nested structure. It's called an AST (abstract syntax tree).
The AST for our example let a = 5;
can be represented something like this:
3. Code generation
Code generation is pretty simple (to understand).
During the code generation step the AST is turned into executable code. Which basically means that the variable a is created by allocating memory, the assignment process and all the charade that follows takes place in code generation.
Now back to where we left off.
JS code execution process
Engine
Complier
Scope
Engine being the manager does only tasks which are demanding. It often outsources some of his work to the compiler and the scope.
When a piece of code is executed, it's the compiler's job to perform tokenizing.
Again, considering our previous example let a = 5;
it would look something like this.
After this process it parses the code into AST. (Parsing)
Now the next logical step would be code generation. Here's the catch. The complier now goes to the scope and asks if there is a variable called a
already declared within the scope. If yes, the compiler proceeds to the next step. If not, then the compiler asks the scope to declare a variable called a. I like to think of the scope as a benevolent bouncer in a night club. It keeps a list of all the guests and if he encounters a stranger he just adds them to the list.
Once a
is identified, the compiler hands over the code execution part to the engine. This is why I had stated that the engine does the heavy lifting (which includes creating memory, assigning value etc).
Before engine takes the helm, it asks the scope if a is accessible. If yes then it proceeds with it's usual routine of creating memory and assigning the value 5 to a and so on. If not, then it will spit out an error.
The below diagram summarizes the whole process
Remember I told you that the engine asks the scope if it can access the variable?
There are two ways it looks if the variable is accessible.
LHS and RHS.
Left hand side look up and Right hand side look up.
A lot many folks in the industry confuse it as looking on the left of the operator and right at the operator. That's just not true.
I'll show you a trick to identify which is LHS and RHS look-up very easily.
IMP!
Wherever you are assigning/passing data it is an LHS look up.
Wherever you are retrieving data it is an RHS loop up.
To get a better understanding consider the example below. Let's start small. We will build up from there.
Eg 1.
let a = 5
;
Here we are simply assigning the literal value 5 to a variable a.
Now go back to the earlier statement and figure out which look-up this is.
Ans.
LHS.
Why ? Cause it's an assignment.
Eg 2.
function foo(a){
console.log(a + 3);
}
foo(5);
Ans.
Here foo(5) is RHS and foo(a) is LHS and a in a + 3
is RHS.
a is retrieved in the latter 2 cases.
That's it folks!
JS compilation and execution is far more complex than what I have described. I have given a high level view on the subject, the rest is out of scope for this post (no pun intended).
Posted on October 28, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.