DEV Community

Cover image for JavaScript Hoisting Explained in details: var, let, const, and Functions
gautam kumar
gautam kumar

Posted on

JavaScript Hoisting Explained in details: var, let, const, and Functions

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Key Points for var hoisting:

  1. The declaration is hoisted, but the assignment is not.
  2. Variables declared with var have function scope, meaning they are accessible anywhere inside the function they are declared in.
  3. Accessing the variable before declaration results in undefined instead of a ReferenceError.

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!");
}
Enter fullscreen mode Exit fullscreen mode

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!");
};
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 with undefined.
  • let and const 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)

Collapse
 
_bkeren profile image
''

the code stops executing after ReferenceError

Collapse
 
gautam_kumar_d3daad738680 profile image
gautam kumar

Yes the code stops executing in case of reference error

Collapse
 
_bkeren profile image
''

your comments in code snippets look as if the code executes after ReferenceError

Thread Thread
 
gautam_kumar_d3daad738680 profile image
gautam kumar

Ok, I understand the confusion here, I will correct it