Hoisting in Javascript
Prerequisite:-
Before getting into the details, let us now cover some topics that help build the mindset needed to understand the runtime dynamic behavior of JavaScript.
Before a computer program is executed, it is either compiled or interpreted. When a language being compiled, the compiler analyzes the code and looks for lexical and syntactic consistency before proceeding to translate it into machine code. Unless a code is conforming to the grammatical rules of that language, the translation won't begin and a syntax error will be raised. This is true for every compiled language not just JavaScript. Here is a simple flow to understand the gist:-
picture credits:- javatpoint.
JavaScript supports Just-In-time compilation, which means it compiles and optimizes code as per the runtime conditions. Javascript being a loosely typed language, this optimization is essential. For example:- let us say we have a loop that prints a thousand strings, but the type string is not specified in the code explicitly. During Just-In-Time compilation which happens at runtime, JavaScript engine identifies that there is a loop involving strings and optimizes the compiled code for strings specifically. This small overhead of dynamic code analysis can create a huge boost in performance in the right situations. The benefits far outweigh the runtime overhead.
I highly recommend that you watch the video below by the Computerphile to understand JIT compilation better.
Ok, we understood what compilation is, but how is it relevant to hoisting?
The takeaway from the prerequisite section should be that compilers and execution environments analyze source codes before execution and perform several actions before and during execution.
What is Hoisting.
Hoisting is the process of lifting up the declarations of variables, classes and functions, and import statements to the top of their scope. Because of this however, a variable or a function written in code can be accessed by the execution environment even before its declaration is executed.
hoisting of variables.
When variables are hoisted, it is only their declarations and the default initialization to 'undefined' that is lifted to the top of the scope. That means, when to try to access a variable whose declaration is not yet executed, you get a value of undefined. This is true for var declared variables.
In case of let and const variables, hoisting is done but not quite like as a var declared variables. They are hoisted, but exist in a Temporal Dead Zone (TDZ) until their declaration is executed. That means, any reference made to a let or a const declared variable before executing their declaration results in a ReferenceError.
hoisting of functions.
When functions are hoisted, they are hoisted completely. This means, the function can be accessed and called from anywhere in its scope irrespective of its lexical placement. The function code is also accessible in the console. How to do that is left to the reader's curiosity.
hoisting of classes.
Just as with let and const variables, class declarations are hoisted but only with their default initialization.
Ambiguity surrounding the definition of hoisting.
Because of the way let and const variables are hoisted, necessarily nullifying the meaning of hoisting, they are commonly referred to as 'non-hoisting declarations'. But because of the effect they have on their scope they are considered to be hoisted somehow. The resulting misconception is that JavaScript beginners often think that it is only the var declared variables that are hoisted.
It is important to understand that the following four behaviors are associated with hoisting:-
Being able to use a variable's value in its scope before the line it is declared. ("Value hoisting")
Being able to reference a variable in its scope before the line it is declared, without throwing a ReferenceError, but the value is always undefined. ("Declaration hoisting")
The declaration of the variable causes behavior changes in its scope before the line in which it is declared.
The side effects of a declaration are produced before evaluating the rest of the code that contains it.
So, it is to be understood that the happening of any of these four is an indication of hoisting. The question is going to be "which of the above four behaviors is shown by let and const declarations??". I am leaving that up to you my readers to explore the Internet and understand.
Why do I need to know this?
There is no direct functional utility to understanding hoisting, however it helps the JavaScript developer write predictable bug-free code improving the readability and maintainability of the code.
An understanding of how JavaScript executes helps developers debug the their code . I will explain this with a personal experience of mine. in the February of this year a few days after I first came across the concept of hoisting, I was helping my friend debug his JavaScript code. He was working with an OpenAI API, and he couldn't process the retrieved the results because of some error. I then used my acquired knowledge of hoisting to console log some variables that were initialized at various points of the code, and then re-run the page. Voila!! We could narrow down to where exactly the code was stuck without introducing any new dummy variables!!.
Of course, this is not what hoisting is intended for, nevertheless the knowledge did help us get out of a bind.
It is considered a best practice to move any var declarations to as top of the code as possible to avoid any kind of unexpected behaviors caused by hoisting.
What next?
I suggest you to explore the concept of hoisting yourself through MDN's JavaScript guide. I also strongly recommend you to watch Akshay Saini's video on youtube where he explains hoisting and demonstrates it on the browser console.
In the next article we will explore Temporal Dead Zone and understand how it is relevant from a developer's perspective.
References:-
Akshay Saini's Video on hoisting.
Subscribe to my newsletter
Read articles from Peddinti Sriram Bharadwaj directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Peddinti Sriram Bharadwaj
Peddinti Sriram Bharadwaj
I am a learner