
What is Hoisting?
Hoisting is a fundamental JavaScript behavior that defines how variable and function declarations are registered during the creation phase of the execution context before code execution begins.
Hoisting is JavaScript's mechanism of allocating memory for variable and function declarations prior to executing line-by-line code.
Core Facts:
- Declarations are hoisted, but initializations are not.
- Function declarations are hoisted completely, allowing them to be invoked before their textual definition.
letandconstdeclarations are hoisted into the Temporal Dead Zone (TDZ) and remain uninitialized until execution reaches their definition.
Variable Hoisting
var Declarations
Variables declared with var are hoisted to the top of their enclosing function or global scope and initialized with undefined.
Example:
JAVASCRIPT1console.log(a); // Output: undefined 2var a = 10; 3console.log(a); // Output: 10
Under the hood:
JAVASCRIPT1var a; // Declaration is hoisted and initialized to undefined 2a = 10; // Assignment happens during the execution phase
let and const Declarations
Unlike var, variables declared with let and const are hoisted without initialization. Accessing them before their declaration line results in a ReferenceError.
Example:
JAVASCRIPT1console.log(b); // ReferenceError: Cannot access 'b' before initialization 2let b = 20;
This behavior is caused by the Temporal Dead Zone (TDZ), which protects variables from premature access.
Function Hoisting
Function Declarations
Function declarations are hoisted with their complete function bodies, enabling calls before their definition in the source file.
Example:
JAVASCRIPT1sayHello(); // Output: Hello, world! 2 3function sayHello() { 4 console.log("Hello, world!"); 5}
Function Expressions and Arrow Functions
Function expressions and arrow functions assigned to variables follow variable hoisting rules rather than function hoisting rules.
Example:
JAVASCRIPT1sayHi(); // TypeError: sayHi is not a function 2 3var sayHi = function() { 4 console.log("Hi!"); 5};
JavaScript hoists sayHi as a variable with value undefined. Attempting to invoke undefined() throws a TypeError.
Summary Comparison
| Feature | var | let and const | Function Declaration | Function Expression |
|---|---|---|---|---|
| Hoisted? | Yes | Yes (in TDZ) | Yes | Follows variable type |
| Usable before declaration? | Yes (undefined) | No (ReferenceError) | Yes | No (TypeError / ReferenceError) |
Best Practices
- Prefer
constandletovervarto enforce block scoping and prevent accidental hoisting side effects. - Declare variables at the top of their respective scopes for clarity and readability.
- Maintain consistent function declaration styles and understand the scope constraints of the Temporal Dead Zone.
Conclusion
Understanding JavaScript hoisting and the execution context lifecycle prevents elusive runtime bugs and enables you to write clean, predictable asynchronous and synchronous code.