🟨 JavaScript Q2 / 121

What is hoisting in JavaScript?

AI-Powered Answer ✓ Answered

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

What is Hoisting?

Conceptually, hoisting means that the JavaScript interpreter moves all variable and function declarations to the top of the current scope (global or function scope) before executing the code. It's important to note that only declarations are hoisted, not initializations.

In reality, the code is not physically moved; instead, the JavaScript engine parses the code and creates an execution context. During the creation phase of the execution context, it identifies all variable and function declarations and registers them in the environment record, making them available before the code execution begins.

How Hoisting Works

Variable Hoisting (var)

When variables declared with var are hoisted, they are initialized with undefined during the creation phase of the execution context. This allows you to access them before their declaration, but their value will be undefined until the line of code where they are assigned a value is reached.

javascript
console.log(myVar); // Output: undefined
var myVar = 10;
console.log(myVar); // Output: 10

// This is how the engine interprets it:
// var myVar;
// console.log(myVar); // myVar is undefined
// myVar = 10;
// console.log(myVar); // myVar is 10

Function Hoisting

Function declarations are fully hoisted. This means both the function's name and its body are moved to the top of the scope. Consequently, you can call a function before its declaration in the code.

javascript
sayHello(); // Output: Hello from hoisted function!

function sayHello() {
  console.log('Hello from hoisted function!');
}

// This is how the engine interprets it:
// function sayHello() {
//   console.log('Hello from hoisted function!');
// }
// sayHello();

Function expressions (anonymous functions assigned to variables) are not hoisted in the same way. Only the variable itself is hoisted (with undefined if var), not the function assignment.

javascript
// myFunction(); // TypeError: myFunction is not a function (if using var) or ReferenceError (if using let/const)
// var myFunction = function() {
//   console.log('This is a function expression');
// };
// myFunction();

Let and Const with Hoisting (Temporal Dead Zone - TDZ)

Variables declared with let and const are also hoisted, but they are not initialized with undefined. Instead, they are placed in a 'Temporal Dead Zone' (TDZ) from the beginning of the scope until their declaration is encountered. Attempting to access them before their declaration results in a ReferenceError.

javascript
// console.log(myLetVar); // ReferenceError: Cannot access 'myLetVar' before initialization
// let myLetVar = 20;
// console.log(myLetVar); // Output: 20

// console.log(myConstVar); // ReferenceError: Cannot access 'myConstVar' before initialization
// const myConstVar = 30;
// console.log(myConstVar); // Output: 30

The TDZ makes let and const more predictable and helps catch bugs related to uninitialized variable access.

Order of Hoisting

If you have both function declarations and variable declarations (using var) with the same name, function declarations take precedence over variable declarations. However, if a variable initialization with var or a let/const declaration follows, it will overwrite or shadow the function name within that scope.

javascript
console.log(testName); // Output: [Function: testName]
var testName = 'I am a variable';
console.log(testName); // Output: I am a variable

function testName() {
  return 'I am a function';
}

Best Practices

  • Always declare your variables and functions at the top of their respective scopes. This makes your code cleaner, easier to understand, and prevents confusion related to hoisting.
  • Prefer let and const over var. They have block scope and a Temporal Dead Zone, which makes variable access more explicit and less prone to hoisting-related issues.
  • Understand how hoisting works, but avoid relying on it as a coding pattern. Explicitly declaring before use is generally better for readability and maintainability.