Understanding Hoisting in JavaScript

Understanding Hoisting in JavaScript

Dipesh Chaulagain
Dipesh Chaulagain

2. Hoisting

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their containing scope (global or function) during the compilation phase, before the code is executed. This means that you can use functions and variables before they are declared in the code.

How Hoisting Works

  1. Variable Hoisting:
    • Only the declaration is hoisted, not the initialization.
    • Variables declared with var are hoisted to the top of their containing function or global scope.
    • Variables declared with let and const are also hoisted but in a different manner (they are not initialized until their definition is evaluated, and accessing them before the declaration results in a ReferenceError).
  2. Function Hoisting:
    • Function declarations are hoisted along with their definitions, meaning the entire function can be used before it is declared.
    • Function expressions and arrow functions are not hoisted in the same way; only the variable declaration is hoisted, not the function assignment.

Examples

Variable Hoisting with var

console.log(x); // undefined
var x = 5;
console.log(x); // 5

What happens here is:

var x;
console.log(x); // undefined
x = 5;
console.log(x); // 5

The declaration var x is hoisted to the top, but the assignment x = 5 remains in place.

Variable Hoisting with let and const

console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
console.log(y); // 10

Variables declared with let and const are hoisted, but they are in a “temporal dead zone” (TDZ) from the start of the block until the declaration is encountered.

Function Hoisting

console.log(add(2, 3)); // 5
function add(a, b) {
  return a + b;
}

What happens here is:

function add(a, b) {
  return a + b;
}
console.log(add(2, 3)); // 5

The entire function add is hoisted to the top.

Function Expression Hoisting

console.log(subtract); // undefined
var subtract = function (a, b) {
  return a - b;
};
console.log(subtract(5, 3)); // 2

What happens here is:

var subtract;
console.log(subtract); // undefined
subtract = function (a, b) {
  return a - b;
};
console.log(subtract(5, 3)); // 2

Only the variable declaration var subtract is hoisted, not the assignment.

Temporal Dead Zone (TDZ)

The TDZ is a behavior where variables declared with let and const cannot be accessed before their declaration is encountered. This is to avoid issues with accessing uninitialized variables.

{
  console.log(a); // ReferenceError: Cannot access 'a' before initialization
  let a = 3;
}

Best Practices

  • Use let and const: Prefer using let and const over var to avoid issues related to hoisting and TDZ.
  • Declare Variables and Functions at the Beginning: Although hoisting allows using functions and variables before their declaration, it’s a good practice to declare all variables and functions at the top of their scope to improve code readability and maintainability.

Conclusion

Hoisting is a fundamental concept in JavaScript that affects how variables and functions are interpreted by the engine. Understanding hoisting helps in writing predictable and bug-free code. It is important to be aware of how var, let, const, and function declarations behave in terms of hoisting to avoid common pitfalls.