JavaScript Hoisting
๐น What is Hoisting?
Hoisting is JavaScript's default behavior of moving declarations of functions and variables to the top of their scope before the code is executed. This means you can use a function or variable before it has been physically declared in the code. However, it's important to understand that only the declarations are hoisted, not the initializations (the assignment of a value).
In simple terms:
JavaScript scans the entire code first, remembers all variable and function declarations, and then starts running the code.
Variable Hoisting
How hoisting works with variables depends on whether you use var, let, or const.
- Using var Variables declared with var are hoisted to the top of their scope and are initialized with a value of undefined. This means you can access the variable before its declaration without an error, but its value will be undefined until the assignment is made. Example: code:
console.log(myVar); // Outputs: undefined
var myVar = "Hello, World!";
console.log(myVar); // Outputs: "Hello, World!"
How JavaScript sees it:
Code
var myVar; // Declaration is hoisted and initialized as undefined
console.log(myVar);
myVar = "Hello, World!"; // Initialization happens here
console.log(myVar);
- Using let and const Variables declared with let and const are also hoisted, but they are not initialized with a default value. Accessing a let or const variable before it is declared will result in a ReferenceError. This is due to the Temporal Dead Zone (TDZ), which is the time from the start of the block until the variable declaration is processed. Example: Code
console.log(myLet); // Throws ReferenceError: Cannot access 'myLet' before initialization
let myLet = "This will not work";
Function Hoisting
- Function Declarations Function declarations are fully hoisted, meaning both the function's name and its entire logic are moved to the top. This allows you to call a function before it is declared in your code. Example: code
sayHello(); // Outputs: "Hello there!"
function sayHello() {
console.log("Hello there!");
}
- Function Expressions Function expressions, where a function is assigned to a variable, are not hoisted in the same way. If the variable is declared with the var keyword, the declaration is hoisted and initialized to undefined. Trying to call it before the assignment will result in a TypeError. If declared with let or const, it will be subject to the Temporal Dead Zone and throw a ReferenceError. Example (with var): code
sayGoodbye(); // Throws TypeError: sayGoodbye is not a function
var sayGoodbye = function() {
console.log("Goodbye!");
};
๐น Example Code
console.log(a);
console.log(b);
console.log(c);
let a = 10;
const b = 20;
var c = 30;
hoistingFunction();
notHostingFunction();
function hoistingFunction() {
console.log('hi');
}
const notHostingFunction = () => {
console.log('hello');
}
๐น Step-by-Step Explanation
During the compilation phase, JavaScript hoists declarations:
var c; // Hoisted and initialized with undefined
let a; // Hoisted but NOT initialized (TDZ)
const b; // Hoisted but NOT initialized (TDZ)
function hoistingFunction(){console.log('hi');} // Fully hoisted
const notHostingFunction; // Declared but not initialized
During execution, code runs line by line:
console.log(a) โ โ Error: Cannot access 'a' before initialization
console.log(b) โ Not reached (script already stopped)
console.log(c) โ Not reached
- Variables with let and const are in the Temporal Dead Zone (TDZ) until their declaration line is executed.
- var is accessible before initialization but holds undefined.
๐น Function Hoisting
โ
Function Declarations
sayHi();
function sayHi() {
console.log('Hello');
}
โ
Works perfectly because function declarations are fully hoisted (both name and body).
โ Function Expressions / Arrow Functions
sayHello(); // Error
const sayHello = () => console.log('Hello');
๐ซ Error: Cannot access 'sayHello' before initialization
Reason: Only the variable declaration (const sayHello) is hoisted, not the function value.
๐น Variable Hoisting Summary
๐น Temporal Dead Zone (TDZ)
The TDZ is the time between the start of the scope and the line where a let or const variable is declared.
Accessing these variables during the TDZ results in a ReferenceError.
Example:
console.log(x); // โ ReferenceError
let x = 5;
๐น Corrected Version of the Example Code
let a = 10;
const b = 20;
var c = 30;
console.log(a); // 10
console.log(b); // 20
console.log(c); // 30
hoistingFunction(); // โ
Prints 'hi'
function hoistingFunction() {
console.log('hi');
}
notHostingFunction(); // โ ReferenceError (Cannot access 'ok' before initialization)
const notHostingFunction = () => {
console.log('hello');
};
๐น Key Takeaways
- Only declarations are hoisted, not initializations.
- var variables are hoisted and initialized with undefined.
- let and const are hoisted but remain in the Temporal Dead Zone until their line of declaration.
- Function declarations are fully hoisted (can be called before they appear).
- Function expressions (arrow or anonymous) behave like variablesโnot callable before initialization.


Top comments (0)