Hoisting is JavaScript’s behavior of moving declarations (not initializations) to the top of their containing scope—either a function or the global scope. This process happens during the compilation phase, before any code is executed.
Function Declarations
In JavaScript, function declarations are fully hoisted. This means that both the function’s name and its implementation are moved to the top of their scope. As a result, you can call a function before it appears in your code. This is similar to languages like C#, where you can call class methods from anywhere within the class, regardless of their order.
Example:
sayHi("rahul");
sum(1, 2);
function sayHi(name) {
console.log(name);
}
function sum(a, b) {
console.log(a + b);
}
Here, both sayHi and sum are called before their definitions. This is possible because JavaScript hoists the entire function declarations, so the engine knows about these functions before any code is executed.
Variable Declarations with let and const
Variable declarations using let and const are also hoisted, but only the declaration is moved—not the initialization. These variables are placed in the temporal dead zone (TDZ) from the start of their scope until the line where they are initialized. During this period, the variable exists but cannot be accessed.
Example:
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 2;
In this case, JavaScript knows about the variable b due to hoisting, but it hasn’t been initialized yet. Trying to access b before its declaration results in a ReferenceError. This behavior helps prevent bugs that might occur when variables are used before they are ready.
Function Expressions and Arrow Functions
When you define a function using a function expression (including arrow functions) and assign it to a variable declared with let or const, only the variable declaration is hoisted—not the function assignment. This means the variable is also in the temporal dead zone until it is initialized.
Example:
sayHi("rahul");
const sayHi = (name) => console.log(name);
Here, JavaScript hoists the declaration of sayHi, but the function is not assigned until that line is executed. If you try to call sayHi before the assignment, you’ll get a ReferenceError:
ReferenceError: Cannot access 'sayHi' before initialization
This happens because, unlike function declarations, function expressions assigned to variables behave just like any other variable declared with let or const.
Hoisting Inside Functions
Just as with the global scope, variable and function declarations inside a function are hoisted to the top of that function's local scope. This means you can reference them anywhere within the function, even before their actual declaration in the code.
Key Points:
Only the declarations are hoisted, not the initializations.
For variables declared with var, the variable is initialized to undefined at the top of the function scope.
For let and const, the variable is hoisted but not initialized (temporal dead zone applies).
Function declarations are fully hoisted and can be called anywhere within the function.
Example:
function demoHoisting() {
// Uncommenting the next line will cause a ReferenceError
// console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 10;
console.log(a); // 10
// Uncommenting the next line will cause a ReferenceError
// console.log(b); // ReferenceError: Cannot access 'b' before initialization
const b = 20;
console.log(b); // 20
sayHello(); // "Hello!"
function sayHello() {
console.log("Hello!");
}
}
demoHoisting();
let a and const b are hoisted but not initialized, so accessing them before their declaration results in a ReferenceError.
The function declaration sayHello is hoisted, so it can be called before its definition.
Summary
Function declarations are fully hoisted; you can call them before their definition in the code.
Variables declared with let or const are hoisted, but not initialized, and are in the temporal dead zone until their assignment line.
Function expressions (including arrow functions) assigned to let or const variables are not available before their initialization, just like any other variable.
Inside functions, the same rules apply: variables and function declarations are hoisted to the top of the function’s local scope.
Understanding hoisting is key to avoiding bugs and writing predictable, robust JavaScript code.
If you’d like to explore this concept even further, I recommend searching the web for more articles, tutorials, and documentation on JavaScript hoisting to gain a deeper understanding!
Top comments (0)