← all writing

Hoisting in JavaScript

Moving the declaration of variables at the top of the scope during the compilation phase is called hoisting. This means that you can use variables and call functions before their actual declarations in the code. First function declarations is hoisted and then variable declarations.

Variable Hoisting

When using the var keyword to declare a variable, the declaration is hoisted to the top of its scope, and the variable is initialized with the value undefined. Let's see an example:

console.log(a);            // undefined
var a = 10;
console.log(a);            // 10

In the above program JavaScript compiler moves declaration of variable at the top.

var a;
a = undefined;
console.log(a);            // undefined
a = 10;
console.log(a);            // 10

Function Hoisting

console.log(a);         // undefined
var a = 10;
console.log(a);         // 10
greet();                // "Hello"
function greet() {
  console.log("Hello");
}

In the above program JavaScript compiler moves declaration of variable and function at the top.

function greet() {
  console.log("Hello");
}
var a;
a = undefined;
console.log(a);        // undefined
a = 10;
console.log(a);        // 10
greet();               // "Hello"

Hoisting of Variables with let and const

In JavaScript, let and const are block-scoped declarations introduced in ECMAScript 6 (ES6). They behave differently from var when it comes to hoisting.

let and const Declaration and Hoisting

When a variable is declared using let or const, it is hoisted to the top of its block scope during the compilation phase, just like var. However, unlike var, let and const variables are not automatically initialized with a value of undefined. Instead, they enter what is known as the "temporal dead zone."

The "temporal dead zone" is a phase between the start of the scope where the let or const variable is declared and the actual line of code where it is defined. During this phase, attempting to access the let or const variable will result in a ReferenceError, as the variable is not yet fully initialized.

Let's illustrate this with an example:

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

In this example, we try to access the let variable a before its actual declaration. This results in a ReferenceError due to the temporal dead zone. Once the variable a is declared with let a = 10, it is fully initialized, and accessing it no longer raises an error.

Questions

1. What will be the output of this program?

console.log(name);
var name = 'Deepak';

Answer — undefined

2. What will be the output of this program?

console.log(name);
let name = 'Deepak';

Answer — ReferenceError: Cannot access 'name' before initialization

3. What will be the output of this program?

function printMessage() {
  console.log(message);
  var message = 'good';
}
 
printMessage();

Answer — undefined

4. What will be the output of this program?

function printMessage() {
  console.log(message);
  const message = 'good';
}
 
printMessage();

Answer — ReferenceError: Cannot access 'message' before initialization