Deep dive into JavaScript Hoisting

What is hoisting?

Hoisting is a JavaScript’s default behavior to move variables and function declarations to the top of the scope. The scope may vary based on where it’s declared. It may be page level, function level or block level. Only declarations are hoisted, not initializations.

Page(Window/Global) Level Hoisting:

By default all the variables declared in the page level will be hoisted automatically. For example, from the below code, the variable currentScope will be hoisted.

console.log(currentScope); //prints undefined and hoisted
var currentScope = "window";

Block Level Hoisting:

Variables declared inside a block will be hoisted both it’s lexical level and it’s block level.

console.log(blockscope);// hoisted, prints undefined
{
console.log(blockscope);// hoisted, prints undefined
var blockscope = "True";
}

Variables declared inside for loop and while loop will be hoisted both in loop’s block level and it’s lexical level.

console.log(isWhileLoop);  //hoisted
while (false) {
console.log(isWhileLoop); //hoisted, prints undefined
var isWhileLoop = "Yes";
}
console.log(isForLoop);  //hoisted
for(var i=0;i<5;i++) {
console.log(isForLoop); //hoisted, prints undefined
var isForLoop = "Yes";
}

Variables declared inside conditional blocks will be hoisted both it’s block level and it’s lexical level.

console.log(isFalse); //hoisted, prints "Yes"
if(false){
console.log(isFalse); //hoisted, prints "Yes"
var isFalse = "Yes";
}
console.log(isFoundDay); //hoisted
console.log(isNotMatching); //hoisted
var day = 3;
switch(day){
case 1:{
break;
}
case 2:{
var isNotMatching = "Yes";
break;
}
case 3:{
console.log(isFoundDay); //hoisted
var isFoundDay = true;
break;
}
}

Hoisting Functions and It’s variables:

Functions with function declarations are automatically hoisted and it can be invoked too. Functions with function expressions are hoisted, but cannot be invoked, as only variable declarations are hoisted.

console.log(sayHelloFunction); //will throw a reference error, var sayHelloFunction is not defined
console.log(typeof sayHello); //prints function, and it can be called too
console.log(sayHello()); //will execute the function
function sayHello(){
console.log(sayHelloFunction); //hoisted
var sayHelloFunction = true;
}

console.log(expFunction); //declaration hoisted, prints undefined
console.log(expFunction());//Throws error, expFunction is not a function
var expFunction = function(){
console.log(isExpFunction); //hoisted, prints undefined
var isExpFunction = true;
}

ES6 let and const hoisting:

ES6 let and const are not hoisted, will throw reference error, if it’s not found the declaration in the calling scope.

console.log(isES6); //not hoisted, will throw ReferenceError
let isES6 = true;
console.log(techStack); //not hoisted, will throw ReferenceError
const techStack = ["JS","HTML", "CSS"];