JavaScript Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables or classes to the top of their scope, prior to execution of the code.
Hoisting allows functions to be safely used in code before they are declared.
Variable and class declarations are also hoisted, so they too can be referenced before they are declared. Note that doing so can lead to unexpected errors, and is not generally recommended.
Hoisting is JavaScript’s default behavior of moving declarations to the top.
However there is a big misconception among developers regarding this concept of hoisting.
Now as a JavaScript developer, it is super important for you to truly understand the concept of hoisting not only because it will give you a better understanding of the language but also because this is one of the most important concepts that can easily award or cost you some points in interview rounds of a web development interview.
Let us see an example to understand more about hoisting
logUsername(); console.log(username); // define the username variable var username = "Alex"; function logUsername() { console.log(username); console.log('logged...'); }
Here is what we get as the output for the above code :
HOW JAVASCRIPT WORK UNDER THE HOOD ?
When the JavaScript Engine goes over your code, it parses it and simply analyze it, it creates something called as the Execution Context. So this execution context is kind of a wrapper around your currently running code. It comprises of the global variable, the this
object (you may know it as the this keyword) and the lexical variable environment of that execution context. Let us see an example first and then we will understand the concept of Hoisting in these examples using the Execution Context:
var num = 10; function foobar() { console.log("function foobar is called!") } foobar(); console.log(num);
If we execute the above code, we get the following output :
Now what will happen if we move the last 2 lines of code in the beginning like this ?
foobar(); console.log(num); var num = 10; function foobar() { console.log("function foobar is called!") }
We will get the following output if we run the above code :
Ideally for this case we would expect JavaScript to raise an exception because the function foobar
is getting called right before it is declared and the variable num
is getting referenced before its declaration.
In this case if we see the output, the function foobar
is getting executed even though we called it way before its declaration point and for the variable num
we are getting an undefined
. This simply means that JavaScript has access to the the foobar
function and the num
variable which is stored somewhere. Now in order to understand this, we need to understand the phases of execution context in JavaScript :
Execution Context comprises of two phases:
During the creation phase of the execution context, JavaScript performs memory space allocation for the functions and the variables that we define. In case of functions, the whole function body gets stored but in case of the variables, it is declared and assigned a default value of undefined
. This entire thing is also termed as Hoisting in JavaScript.
An important thing to understand is, the value of num
is set to undefined
during this phase because JavaScript in this case finds a variable num
defined somewhere in our above code. If we remove the line var num = 10
then it will result in an error
Uncaught ReferenceError: num is not defined
.
So in the above when JavaScript ran console.log(num)
, the var num
is not assigned any value at that point so it picked up the value from the memory space which is set to undefined
during the creation phase and printed that value.
As a side note, it is recommended not to rely on hoisting, that means it is a good practice to declare and define the variables and the functions before they are referred.
2. EXECUTION PHASE:
In this phase, JavaScript executes our code line by line and assigns the value to all our variables. In our above example, a value of 10 is assigned to the variable num
To understand this, let us have a look at the below code :
function foobar() { console.log("function foobar is called!") } foobar() console.log(num); var num = 10; console.log(a)
Since we now understand the different phases of Execution, we can easily say by looking at the above code that the output of our code should be :
- The function
foo
gets called and it prints the following message to the console : function foobar is called! - Now on the next line as we know that during the creation phase, JavaScript assigns a default value of
undefined
to thenum
variable. So this givesundefined
as output. - The last line logs 10. Now the reason for getting 10 here is that in the execution phase, assignment of variable happened and
num
got the value of 10
So this is it for this article. Thanks for reading.
If you enjoy my articles, consider following me on Twitter for more interesting stuff :
⚡Twitter : https://twitter.com/The_Nerdy_Dev
Don’t forget to leave a like if you loved the article. Also share it with your friends and colleagues.