Hoisting in JavaScript is a behavior in which variable and function declarations are moved to the top of their containing scope (global or function) during the compile phase, before the code execution. However, only the declarations are hoisted, not the initializations.
Variable Hoisting
For variables declared with var, the declaration is hoisted but not the initialization.
console.log(a); // Output: undefined
var a = 5;
console.log(a); // Output: 5
In the example above, the variable a is hoisted to the top of its scope, so the first console.log(a) doesn't throw an error but returns undefined because the initialization (a = 5) is not hoisted.
Function Hoisting
Function declarations are fully hoisted, meaning both the declaration and the body of the function are moved to the top of their scope.
hoistedFunction(); // Output: "This function is hoisted!"
function hoistedFunction() {
console.log("This function is hoisted!");
}
In this case, the function hoistedFunction can be called before its actual declaration in the code.
Let and Const
Variables declared with let and const are also hoisted but are not initialized. They remain in a "temporal dead zone" from the start of the block until the declaration is encountered.
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
console.log(b); // Output: 10
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 20;
console.log(c); // Output: 20
In the above example, accessing b or c before their declarations will throw a ReferenceError because they are in the temporal dead zone.
console.log(x); // undefined
var x = 10;
hoisted(); // "Function hoisted!"
function hoisted() {
console.log("Function hoisted!");
}
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 20;
console.log(z); // ReferenceError: Cannot access 'z' before initialization
const z = 30;
In summary:
Variables declared with var are hoisted but initialized to undefined.
Function declarations are fully hoisted.
Variables declared with let and const are hoisted but not initialized, leading to a temporal dead zone.