Hoisting is something you will stumble across millions of times whether you are writing your own code or even in an interview.
The process of storing variable and function declarations in memory prior to execution is called hoisting.
Before you continue further, make sure to get aquatinted with Variable Declarations in JavaScript, Function Declarations & Function Expressions, and Execution Context in JavaScript. These topics will help you a lot to understand hoisting in this article.
What exactly is hoisting?
When it comes to hoisting, it’s important to understand that declaration and assignment are different things.
When we declare variables in JavaScript they are moved to the top of the scope while the assignments stay where they are.
When the browser JavaScript engine starts reading the code, first of all, it will find the variable or function declarations and stores them in a memory which will be used later on.
This memory is also called a variable object which is an important part of the creation phase.
Before the code execution, there is another phase which is called the creation phase where one of the processes is storing variables in memory.
How are variables stored in memory?
Variables keywords defined with var, let or const behave differently when it comes to hoisting and so does a function.
As I already mentioned, when a variable declaration is saved in the memory, it doesn’t come along with its value, only the declaration — specifically the name. However, they receive a default value in the beginning.
When the variable with the keyword var is declared, it is saved in the variable object with a default value undefined.
Now imagine if I tried to console log variable first and declare it later. What will happen?
As you see, it outputs undefined. Why? Because even though the console log is first according to the order, when it comes to the code preparation, the engine will skip this console log because it will make sure it saved the variable declaration first.
But when it did save our variable, it gave it the default value of undefined. That’s why the console log gave us a default value of var — undefined.
Next, we have variables declared with the let and const keywords which are newer than the var. When it comes to these keywords, the process is the same.
However, they are not given the value and are not initialized nor given any default value. They are still kind of saved in the memory but didn’t initialize yet.
And, finally, besides variable declarations, we also have functions that are saved in the variable object during the creation phase.
Functions are saved as a reference to the whole function. Reference is kind of a copy of the original.
Now we know how things are saved during the very phases of code parsing. The variable declared with var is saved as undefined, const and let saved as <uninitilized>, and the functions saved as <func>.
How do variables behave during hoisting?
Considering the fact that hoisting is saving variables into the memory before the code execution it means that no matter where you declare a variable, it will always be a priority to save its declaration.
Let’s try to console log variables and invoke the function first and only then declare them. What do you think would happen with each of them?
The keyword var
We already saw this example previously and the output here will be undefined because the variable declaration var is saved with a default value of undefined.
The keyword let
The let keyword is saved in memory but is not initialized meaning that when we try to access it will throw a ReferenceError because there was no initialization done.
The keyword const
The const keywords behave exactly like the let keyword.
The function
Functions are saved as a reference to the function and as you can see we can call the function and declare it later on. This behavior means that functions can be hoisted.
It’s important to note that functions can be written in different ways. For example, you can also save a function inside a variable which means using a function expression.
In this case, a function will not be hoisted because we saved it in a variable and it will behave like a variable, not like a function!
Why did this code throw ReferenceError? Because we saved a function inside a variable keyword let so it behaves like the let keyword.
Conclusion
Hoisting is an essential concept to understand in JavaScript. It refers to the process of storing variable and function declarations in memory prior to execution. The behavior of variable declarations with var, let, and const keywords differ when it comes to hoisting, and functions are saved as a reference to the whole function.
The order in which variables and functions are declared is crucial, as the declaration is always prioritized during hoisting. It is important to note that functions can be hoisted, but they can also be saved in a variable using a function expression, which behaves like a variable, not like a function. Understanding hoisting can help you write more efficient and error-free code in JavaScript.
To avoid the error the easiest way is to always declare variables at the very top of the code as it will save you from a lot of trouble!
If you are a professional and you know exactly what you are doing, of course, it’s not mandatory but we are all human and mistakes are inevitable.