DEV Community

Cover image for ๐Ÿ”ฅ๐Ÿ•บ๐Ÿผ JavaScript Visualized: Hoisting
Lydia Hallie
Lydia Hallie

Posted on • Edited on

๐Ÿ”ฅ๐Ÿ•บ๐Ÿผ JavaScript Visualized: Hoisting

Hoisting is one of those terms that every JS dev has heard of because you googled your annoying error and ended up on StackOverflow, where this person told you that this error was caused because of hoisting ๐Ÿ™ƒ So, what is hoisting? (FYI - scope will be covered in another post, I like to keep posts small and focused)

If youโ€™re new to JavaScript, you may have experienced โ€œweirdโ€ behavior where some variables are randomly undefined, ReferenceErrors get thrown, and so on. Hoisting is often explained as putting variables and functions to the top of the file but nah, thatโ€™s not whatโ€™s happening, although the behavior might seem like it ๐Ÿ˜ƒ

When the JS engine gets our script, the first thing it does is setting up memory for the data in our code. No code is executed at this point, itโ€™s simply just preparing everything for execution. The way that function declarations and variables are stored is different. Functions are stored with a reference to the entire function.

With variables, itโ€™s a bit different. ES6 introduced two new keywords to declare variables: let and const. Variables declared with the let or const keyword are stored uninitialized.

Variables declared with the var keyword are stored with the default value of undefined.

Now that the creation phase is done, we can actually execute the code. Let's see what happens if we had 3 console.log statements on top of the file, before we declared the function or any of the variables.

Since functions are stored with a reference to the entire function code, we can invoke them even before the line on which we created them! ๐Ÿ”ฅ

When we reference a variable declared with the var keyword before their declaration, itโ€™ll simply return its default value that it was stored with: undefined! However, this could sometimes lead to "unexpected" behavior. In most cases this means youโ€™re referencing it unintentionally (you probably donโ€™t want it to actually have the value of undefined) ๐Ÿ˜ฌ

In order to prevent being able to accidentally reference an undefined variable, like we could with the var keyword, a ReferenceError gets thrown whenever we try to access uninitialized variables. The "zone" before their actual declaration, is called the temporal dead zone: you cannot reference the variables (this includes ES6 classes as well!) before their initialization.

When the engine passes the line on which we actually declared the variables, the values in memory are overwritten with the values we actually declared them with.

(Oops I notice now this should be number 7. Will update asap ๐Ÿ˜ฌ)


All done! ๐ŸŽ‰ Quick recap:

  • Functions and variables are stored in memory for an execution context before we execute our code. This is called hoisting.
  • Functions are stored with a reference to the entire functions, variables with the var keyword with the value of undefined, and variables with the let and const keyword are stored uninitialized.

I hope that the term hoisting is a bit less vague now that we've looked at what's happening when we execute our code. As always, don't worry if it still doesn't make a lot of sense yet. You'll get a lot more comfortable with it the more you work with it. Feel free to ask me for help, I'd love to help you! ๐Ÿ˜ƒ

Top comments (59)

Collapse
 
aminnairi profile image
Amin

Your GIFs are on point! Very good article. I think most of us know or have heard about hoisting but this makes it totally clear in my head now. Keep up the good work!

Collapse
 
jimisweden profile image
Jimi Friis • Edited

It's such a simple thing to explain when looking at yours.. I wonder why so many teach the "Hoisting is often explained as putting variables and functions to the top of the file" - perhaps that's what they learned; perhaps it is the fallacy of thinking "people won't understand because it's complex".
If someone would have asked me to explain hoisting before reading this article I would fall back on that explanation but not really knowing why; now I know better! I have quite good understanding of javascript (for being a mostly C# developer - learning react) and like to know what is going on, one of my favorites in the JS world to read and listen to is Kyle Simpson ('You don't know JS' , + 'Yet') - he is awesome , but you know what.. you, Lydia, are fantastic teacher and a โญ on the same sky as Kyle.

I hope you take this advantage to a next level and produce courses on Udemy and/or Pluralsight - I think you could make a fortune (or at least some extra cash) on it ๐Ÿ˜„

Keep it up ๐Ÿ’š !
//Jimi

Collapse
 
apisurfer profile image
Luka Vidakoviฤ‡

It's a nice refreshment to see gifs that break up the text to digestible chunks while also helping with the visualization. Keep it up!

Hoisting is often explained as putting variables and functions to the top of the file

I can see why it's described that way to some extent. Parser needs to go over the whole file/script, and it only does something meaningful with functions, and vars at first. So at the top of the file, very first line, you already have the access to those identifiers.

Collapse
 
lydiahallie profile image
Lydia Hallie

Itโ€™s just important to understand that the parser is not actually physically moving them to the top - as some people like to explain it

Collapse
 
apisurfer profile image
Luka Vidakoviฤ‡

Yup I agree. Semantically it only makes difference with vars, but you descriptions are to the point ๐Ÿ‘Œ

Thread Thread
 
shafkathullah profile image
Shafkathullah Ihsan

Testing comment UI...

Thread Thread
 
shafkathullah profile image
Shafkathullah Ihsan • Edited

2Testing comment UI...

Collapse
 
islamhanafi94 profile image
Islam Hanafi Mahmoud

First things first, thank you Lydia for this amazing topic. and I've a question regarding using let.

I think let variables is initialized to with undefined. but due to being in temporal zone it's value is inaccessible.

I tried

let x;
console.log(x); // resulting >> undefind

Collapse
 
swasdev4511 profile image
Swastik Upadhye

Yes this is true... The value will be accessible only after the temp dead zone expires...

Collapse
 
fahim04blue profile image
Shahriar Saleh Fahim

It results undefined because you have initialized the variable 'x' already but haven't defined the variable with any value. This is why it prints out undefined.

Collapse
 
matijazx profile image
Matija X

That's reason I love this site. I just learn JS and term hoisting was unknown for me until this moment. I read text above and resolve my doubts. Thx!

Collapse
 
saurabhdaware profile image
Saurabh Daware ๐ŸŒป

Thank you for explaining how it works internally "var brings variables to top" totally makes sense now!

Thank you for sharing! deserves a lot of ๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„

Collapse
 
lfkwtz profile image
Michael Lefkowitz

Love this entire collection, Lydia. Shared them all in my react native newsletter

Collapse
 
namkwon profile image
Nam Kwon

Great article! What about const function? ex. const sum = (x,y) => x+y

Collapse
 
swasdev4511 profile image
Swastik Upadhye

When it comes to const ... They should be assigned some value at the tym of declaration.... So anyway we will get an error if we try to access them b4 declaration

Collapse
 
beginwithjs profile image
beginWithJS

You may consider it as the "hoisting variable const" situation.

Collapse
 
tykhan profile image
tykhan

Also, important thing that arrow functions aren't hoisted. Could be confusing one for somebody.

Collapse
 
savokiss profile image
savokiss

Hi, Lydia~ Very nice articles~ Can I translate this series articles into Chinese, I'll keep the original links~