Compilation and Scope in Javascript
I’m writing in order to share what I’ve learned from the You Don’t Know JS book series. In this post I’m talking about the first chapter “What is Scope” of the second book Scope & Closures.
Compiler v.s Interpreter
Interpreter & Compiler are programs that convert our program into the machine language.
An interpreter reads a program line by line, reading every expression and gives output if the program is correct and it stops and gives error when it encounters the first mistake in any line of code.
A compiler does not run the code line by line, it puts together the whole code and gives output if the program is correct if not it gives an error.
Javascript interpreted or compiled?
It is thought that javascript is interpreted…but it is an urban legend because in reality is compiled. 😱
Its compilation is not made in the traditional way (compiling all the code before) but happens every time before the execution of the code.
A traditional compiler will treat the statement var foo = 4;
like this:
- It breaks
var foo = 4;
into a separate pieces. - It creates an ‘abstract syntax tree’ from the pieces.
- Transforms the tree into computer language instructions, and this instructions are the ones that will create the variable
foo
. - The assignment of the value
4
will happen during the execution, which is not part of the compilation.
Engine, Compiler & Scope
You Don’t Know Js book approaches the explanation of a program processing using a human approach towards the main elements that take part in the process.
So the basic characters of the processing are:
Engine: the boss, program included in the browser, this dude is responsible for starting and finishing the compilation and executes the code.
Compiler: friend of Engine, this guy does the compiling itself, the way it’s explained in the previous section.
Scope: friend of Engine and Compiler, scope is responsible for knowing all the declared variables and which is their accessibility.
Team working together
So going back again to var foo = 4;
Engine sees this statement in two pieces “Compiling part” — “Execution Part”
Compilation part
So Engine asks Compiler to compile the code:
- Break it into chunks and create the tree.
- Code generation, for this part compiler talks with Scope and Engine. This is what they talk about
Compiler: Does var foo
already exist?
Scope: No, it does not exist.
Compiler: Cool, so Scope could you declare var foo?
Scope: Perfect, variable created
If Scope tells that the variables already exists Compiler will not ask her to create another one.
Execution part
Once the variable is created Compiler asks Engine to assign a value of 4 to foo. foo = 4
Before assigning the value engine talks to Scope if the variable is accessible from the same level if not we will move to a more global one to find the variable. When variable is find the value is assigned, if not the Engine will throw an error.
The type of errors that throws the Engine are the next ones:
ReferenceError
variable not found in any of the scopes
TypeError
implies that variable was fount, but that you tried to do something with it that is impossible, like trying to execute-as-function a non-function value, reference a property on a null
or undefined
value.
Review
Who defines how and where the variable can be accessed? The Scope.
Javascript program transformation into machine language occurs in 2 steps: compilation and execution.
During the compilation Compiler talks with Scope about the existence of the variable declared in the statement, if the variable is not declared then Scope creates it, once the variable is created Compiler informs Engine about it.
During the execution Engine talks with Scope and asks to it if the variable is accessible from the actual level if not he asks Scope to go and find the variable in a higher level. Once the variables is found Engine assigns the value to it.
If the variable does not exist in any of the levels the Engine throws the ReferenceError
message.
If the variable does exist but the actions that the program wants to do with it are not possible Engine throws TypeError
message.