Intro
Can you tell what would these three console.log below prints out?
console.log('x is', x)
var x
console.log('x is', x)
x = 5
console.log('x is', x)
If not, stay with me, and Iāll try my best to demystify hoisting.
And even if you know what they print out, if you canāt explain the why, stick around. You might learn something new!
Hoisting
Hoisting is notoriously one of the most confusing aspects for those who are new to the language, or even with some experience ā youāve heard of them, you know it exists, you know it happensā¦ but you donāt really know what exactly is happening behind the scene.
Often itās explained as if the variable and function declarations are physically moved to the top of the code. But thatās not what is happening. In order to understand hoisting, you really need to understand different phases in which JavaScript engine goes through your code.
Note: let/const/class declarations behave differently. I think itās best to understand hoisting with var/function first, so I will keep them for another time. In this post, I will start off by explaining variable hoisting.
JavaScrip Engine
We canāt talk about JavaScript without JavaScript engine. It is a programme which reads and runs JavaScript code. Itās the core of what makes it possible to run your beautiful code in web browsers. For now, itās enough to know that it does its job in two phases: the memory creation phase and the execution phase, and that our code wonāt be executed until the second phase.
Browser Developer Tool
Enough talking! Letās go through some examples of hoisting. If you want to quickly try out the examples as you go along, you can do so by opening the developer tool in your browser (shortcut for Chrome is alt + cmd + i) and go to the console panel.
Tips for running multi-line code in developer tool: shift + enter to go to the new line, then press enter when you want to execute them. Or simply copy and paste the whole code, then hit enter.
Variable Hoisting
Alright, hereās the first one.
console.log(x)
// ReferenceError: x is not defined
Okay, I hear you. This is not actually an example of hoisting. The variable x is not declared anywhere in the code, so it will result in a big red ReferenceError, complaining that x is not definedā fair enough!
What about this one?
console.log(x)
var x
// undefined
At the first glance, you may think that itās a lot like the first example. However, this code doesnāt throw an error. It executes and prints out a value of undefined. Itās important to note that, in JavaScript, undefined is an actual value. So this is basically JavaScript engine interpreting var x = undefined, just like var x = 5 or var x = āstringā.
The key here is that x is defined and available before its declaration ā yes, this is a legitimate example of hoisting. Hence, the example 2 is practically same as:
var x
console.log(x)
But who sets the value of x to undefined? I certainly didnāt, did I?
This is a job of the JavaScript engine. During the memory creation phase, it recognises variable declarations as it reads the code, initialises them to undefined and puts them into memory to be used during the execution phase.
Letās look at another example. What will the console.log output?
console.log(x)
var x = 10
// undefined
You might have guessed that it would print out 10, because you initialised x to 10. But the console.log outputs undefined. Why??
Here is the gotchaā¦ initialisations are not hoisted.
During the memory creation phase, the JavaScript engine recognised the declaration of x (var x), automatically initialised x to undefined, and made it available. However, as the initialisation (= 10) didnāt get hoisted, value of x stayed as undefined when the execution reached console.log at line 1.
If we add another console.log at line 3, the second output will be 10, because by then x is reassigned to 10.
console.log(x)
var x = 10
console.log(x)
// undefined
// 10
Got it?
Please post any feedback, questions, or requests for topics. I would also appreciate š if you like the post, so others can find this too.
Top comments (1)
Nice. More details at devopedia.org/hoisting