Hoisting in JavaScript – Explained with Examples
Hoisting refers to JavaScript giving higher precedence to the declaration of variables, classes, and functions during a program’s execution.
Hoisting makes the computer process declarations before any other code.
For instance, consider this snippet:
{ // Declare a variable: let bestFood = "Fish and Chips";
// Declare another variable: let myBestMeal = function () { console.log(bestFood); let bestFood = "Vegetable Fried Rice"; };
// Invoke myBestMeal function: myBestMeal();}
// The code above will return:// "Uncaught ReferenceError: Cannot access 'bestFood' before initialization"
The snippet above returned a ReferenceError
because of the order of precedence by which the computer executed each code.
In other words, the program’s declarations got higher precedence over initializations, invocations, and other code.
Let’s go through a step-by-step tour of how JavaScript executed the snippet above.
How JavaScript Hoisting Works
Below is a walk-through of how JavaScript executed the previous snippet.
1. JavaScript parsed the first bestFood
declaration
let bestFood; // This is the first bestFood declaration in the program
The first bestFood
variable declaration is the first code the computer analyzed.
Note that after the computer read the bestFood
variable declaration, JavaScript automatically kept the variable in a temporal dead zone until it got fully initialized.
Therefore, any attempt to access bestFood
before its complete initialization would return a ReferenceError
.
2. The computer parsed myBestMeal
variable declaration
let myBestMeal;
The myBestMeal
variable declaration was the second code JavaScript analyzed.
Immediately after the computer read the myBestMeal
variable declaration, JavaScript automatically kept the variable in a temporal dead zone until it got fully initialized.
Therefore, any attempt to access myBestMeal
before its complete initialization would return a ReferenceError
.
3. The computer initialized the bestFood
variable
bestFood = "Fish and Chips";
The computer’s third step was to initialize bestFood
with the "Fish and Chips"
string value.
Therefore, invoking bestFood
at this point would return "Fish and Chips"
.
4. JavaScript initialized myBestMeal
variable
myBestMeal = function () { console.log(bestFood); let bestFood = "Vegetable Fried Rice";};
Fourthly, JavaScript initialized myBestMeal
with the specified function. So, if you had invoked myBestMeal
at this point, the function would have returned.
5. The computer invoked myBestMeal
’s function
myBestMeal();
The invocation of myBestMeal
’s function was the computer’s fifth action.
After the invocation, the computer processed each code in the function’s block. However, the declarations had higher precedence over other code.
6. JavaScript parsed the function’s bestFood
declaration
let bestFood; // This is the second bestFood declaration in the program
JavaScript’s sixth task was to analyze the function’s bestFood
variable declaration.
After the analysis, JavaScript automatically kept the variable in a temporal dead zone—until its complete initialization.
Therefore, any attempt to access bestFood
before its complete initialization would return a ReferenceError
.
7. The computer parsed the function’s console.log
statement
console.log(bestFood);
Finally, the computer read the console.log
statement—which instructed the system to log bestFood
’s content to the browser’s console.
However, remember that the computer has not fully initialized the function’s bestFood
variable yet. As such, the variable is currently in a temporal dead zone.
Therefore, the system’s attempt to access the variable returned a ReferenceError
.
Wrapping It Up
Let’s see the previous walk-through of our program in one piece:
let bestFood; // 1. JavaScript parsed the first bestFood declaration
let myBestMeal; // 2. the computer parsed myBestMeal variable declaration
bestFood = "Fish and Chips"; // 3. the computer initialized the bestFood variable
myBestMeal = function () { console.log(bestFood); let bestFood = "Vegetable Fried Rice";}; // 4. JavaScript initialized myBestMeal variable
myBestMeal(); // 5. the computer invoked myBestMeal's function
let bestFood; // 6. JavaScript parsed the function's bestFood declaration
console.log(bestFood); // 7. the computer parsed the function's console.log statement
// "Uncaught ReferenceError"// bestFood's invocation returned an Error
You can see that JavaScript processed the program’s declarations before other code.
The parsing of declarations before other code in a program is what we call “hoisting”.