Javascript Phases and a bit of Hoisting.

Jon SY Chan
4 min readSep 17, 2019

Javascript has always been quirky to me. There’s always something deeper to learn about it and how it ticks. One thing that lead me into a rabbit hole is the concept of hoisting. I will spend this blog breaking that investigation down.

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.

https://www.w3schools.com/js/js_hoisting.asp

This is important to understand when writing javascript apps so you don’t encounter any unusual behavior of having variables undefined or changed when you don’t expect it to. This is also the reason the concepts of let and const (block scoped and not initialized with undefined upon declaration)were developed (ES6).

Here is an article regarding the issues of var: https://dev.to/sarah_chima/var-let-and-const--whats-the-difference-69e

The concept of hoisting was created by developers to explain what happens during the compilation phase when variables and function declarations are moved — or hoisted — to the top of their containing scope

https://john-dugan.com/hoisting-in-javascript/

So I asked myself, when does this “hoisting” actually happen for Javascript? I remembered hearing that Javascript was an interpreted language. This was the case when Javascript was first created. Originally each line would be read and interpreted by the browser and than subsequently run.

More modern browsers use a technology known as Just-In-Time (JIT) compilation, which compiles JavaScript to executable bytecode just as it is about to run.

https://web.stanford.edu/class/cs98si/slides/overview.html

This very “out-of-the-box” nature of javascript allows it to be run on any device.

Javascript is run with the browser engine like V8 for chrome or SpiderMonkey for Firefox. Different browsers have different engines. All these engines pretty much combine the interpreter and the compiler in one.

Here are the differences between the two: https://www.programiz.com/article/difference-compiler-interpreter

In summary compiler and interpreters convert our source code (high level language) to machine code so our computers can understand and run it. Compiler translates and optimizes the language as a whole while an interpreter immediately goes line by line and translates to run (oversimplified).

Many of these Javascript engines have actually blurred the line between Interpreted and Compiled so this should be noted as point of debate.

In our javascript engine there are pretty much two things that happen, a compilation phase then an execution phase. During the compilation phase the “hoisting” (lexing and tokenizing) phenomenon of variables occurs.

Here is Peter Shan’s explanation:

Whenever v8 enters the execution context of a certain code (function); it starts by lexing or tokenizing the code. Which mean it will split your code into atomic tokens like foo = 10.

After analyzing the entire current scope, it parses a translated version of into an AST (for Abstract Syntax Tree).

Each time it encounters a declaration, it sends it to the scope to create the binding. For each declaration it allocates memory for that variable. Just allocates memory, doesn’t modify the code to push the declaration up in the codebase. And as you know, in JS, allocating memory means setting the default value undefined.

After that, each time it encounters an assignment or an evaluation, it asks the scope for the binding. If not found in the current scope, it goes up into parent scopes until it finds it.

Then it generate the machine code that the CPU can execute.

Finally, the code is executed.

http://voidcanvas.com/is-javascript-really-interpreted-or-compiled-language/

This link provides great psuedo-code examples of how hoisting occurs during this compilation phase. https://john-dugan.com/hoisting-in-javascript/

I will next be doing a dive into the V8 javascript engine for chrome since Node.js is run based on that engine. Look into concepts like inline caching which is how V8 optimizes by reducing lookup operations. I know for now it’s been kind of an oversimplification but it really helps to have somewhat of an understanding of javascript under the hood. Helps for future debugging!

--

--