Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their containing scope during the compile phase, before code execution.
This means you can use variables and functions before they are declared in your code.
However, only the declarations are hoisted, not the initializations.
Hoisting with var
When using var
, the variable declaration is hoisted to the top of its scope (global or function scope), but the initialization remains in place. If you try to access the variable before initialization, it will return undefined
.
Example 1: Hoisting with var
console.log(a); // undefined
var a = 10;
console.log(a); // 10
Explanation:
Behind the scenes, JavaScript interprets the code like this
var a; // Declaration is hoisted to the top
console.log(a); // undefined (since initialization hasn't happened yet)
a = 10; // Initialization remains in place
console.log(a); // 10
Key Points for var
hoisting:
- The declaration is hoisted, but the assignment is not.
- Variables declared with
var
have function scope, meaning they are accessible anywhere inside the function they are declared in. - Accessing the variable before declaration results in
undefined
instead of aReferenceError
.
Hoisting with let
and const
Variables declared with let
and const
are hoisted, but they are not initialized. Accessing them before declaration results in a ReferenceError due to the "Temporal Dead Zone (TDZ)."
Example 2: Hoisting with let
and const
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 20;
console.log(b); // 20
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 30;
console.log(c); // 30
Explanation:
Behind the scenes, JavaScript hoists the declarations but doesn't initialize them:
// Declarations are hoisted, but they are in the Temporal Dead Zone (TDZ)
let b; // Hoisted, but inaccessible before initialization
const c; // Hoisted, but inaccessible before initialization
console.log(b); // ReferenceError
b = 20;
console.log(b); // 20
Key Points for let
and const
hoisting:
The declaration is hoisted, but initialization is not.
Accessing them before initialization throws a ReferenceError.
Variables have block scope, meaning they are only accessible within the block {}
they are defined in.
const
must be initialized at the time of declaration, unlike let
.
Hoisting in Function Declarations vs Function Expressions
Function Declarations (Hoisted)
Function declarations are hoisted entirely, meaning they can be called before their declaration.
sayHello(); // Works fine
function sayHello() {
console.log("Hello!");
}
Function Expressions (Not Hoisted Fully)
Function expressions (assigned to variables) are subject to variable hoisting rules.
greet(); // TypeError: greet is not a function
var greet = function () {
console.log("Hi!");
};
In the above case, greet
is hoisted, but it is treated as undefined
before initialization.
Temporal Dead Zone (TDZ) with let
and const
The Temporal Dead Zone (TDZ) is the period between the start of a block and when a variable is declared. During this period, any access to the variable results in a ReferenceError
.
console.log(myVar); // ReferenceError
let myVar = 50;
console.log(myVar); // 50
In the above example, the area before the let myVar
declaration is the TDZ, meaning you cannot access myVar
before it's declared.
Comparison of var
, let
, and const
in Hoisting
Feature | var | let | const |
---|---|---|---|
Hoisted? | Yes | Yes | Yes |
Initialization? |
undefined (default) |
No (TDZ occurs) | No (TDZ occurs) |
Scope | Function Scope | Block Scope | Block Scope |
Reassignment? | Yes | Yes | No |
Must initialize? | No | No | Yes |
Conclusion
- Hoisting moves variable and function declarations to the top of the scope.
-
var
is hoisted and initialized withundefined
. -
let
andconst
are hoisted but not initialized (TDZ applies). - Function declarations are hoisted, but function expressions are not fully hoisted.
- Always follow best practices to write predictable and maintainable code.
Top comments (4)
the code stops executing after ReferenceError
Yes the code stops executing in case of reference error
your comments in code snippets look as if the code executes after ReferenceError
Ok, I understand the confusion here, I will correct it