JavaScript Hoisting

JavaScript Hoisting

How hoisting behaves for variables and functions

During the creation phase, the JavaScript engine moves the variable and function declarations to the top of your code. This feature is known as hoisting in JavaScript.

when you execute JS code, JavaScript Engine creates Gobal Execution Context - which has two phases : 1) Creation and 2) Execution

how variable behaves during hoisting

scenario 1: Use of variable before it gets declare - type VAR

console.log(normalHoisting) //  undefined
var normalHoisting = "Normal";

Due to hoisting feature , above code implicitly execute as:

var normalHoisting;
console.log(normalHoisting) //  undefined
normalHoisting = "Normal";

Technically speaking, during the creation phase of the global execution context, the JavaScript engine places the variable normalHoisting in the memory and initializes its value to undefined.

scenario 2 : Use of variable before it gets declare - type Let/const:

Hoisting don't work with Let keyword

console.log(letHoisting) //  Uncaught ReferenceError: Cannot access 'letHoisting ' before initialization"
let letHoisting = "Let Variable";

The JavaScript issues the following error:

"ReferenceError: Cannot access 'counter' before initialization"

The error message explains that the counter variable is already in the heap memory. However, it hasn’t initialized.

Behind the scenes, the JavaScript engine hoists the variable declarations that use the let keyword. However, it doesn’t initialize those variables. Notice that if you access a variable that doesn’t exist, the JavaScript will throw a different error:

console.log(randomVariable) //  ReferenceError: randomVariable is not defined
var normalHoisting = "Normal";
let letHoisitng = letHoisitng";

Here is the same error for let and var

"ReferenceError: randomVariable is not defined

how Functions behaves during hoisting

Scenario 1 : How Hoisting works for declarative functions

let result=isHoistingDeclarativeFunction();
console.log(result); // true
function isHoistingDeclarativeFunction(){
return true;
}

In this example, we called the isHoistingDeclarativeFunction() function before defining it. The above code is equivalent to the following:

let result;  //variable hoisting
function isHoistingDeclarativeFunction(){
return true;
} // function hoisting
result=isHoistingDeclarativeFunction();
console.log(result); // true

Scenario 2 : How Hoisting works for Function expressions and Arrow functions

console.log(isFunctionExpressionVar()); // isFunctionExpressionVar is not a function"
console.log(isFunctionExpressionLet ()); // isFunctionExpressionLet is not a function"
var isFunctionExpressionVar =function (){
return true;
}

let isFunctionExpressionLet =function (){
return true;
}

The above code is equivalent to the following after Hoisting:

isFunctionExpressionVar() is not a function because of hoisting , isFunctionExpressionVar still a variable with undefined value.


var isFunctionExpressionVar ;
let isFunctionExpressionLet ;
console.log(isFunctionExpressionVar()); // isFunctionExpressionVar is not a function"
console.log(isFunctionExpressionLet()); //Cannot access 'isFunctionExpressionLet' before initialization"
var isFunctionExpressionVar =function (){
return true;
}

let isFunctionExpressionLet =function (){
return true;
}

Same failure we can see in arrow function :

console.log(isArrrowFunction()); //Cannot access 'isArrrowFunction' before initialization"
let isArrrowFunction = () =>true;

Summary

  1. During variable hoisting, JS engine move the Var type variable to top, declares it and initialize with undefined value . Hence , such variables are available for use even before its declaration in code. No Error
  2. During variable hoisting, JS engine move the Let type variable to top, declares it but didn't initialize it . Hence , such variables are not available for use before its initialization. If try to use it, then getting Cannot access 'variableName' before initialization" error.
  3. During function hoisting, JS engine move the Declarative Functions to top, declares it . Hence , such Functions are available for use even before its declaration in code. No Error
  4. Function expressions and arrow functions aren’t hoisted. Only variable referencing the function are getting hosited. Hence

var type variable throw - "is not a function" error

let type variable throw - "Cannot access before initialization" error

Reference : javascripttutorial.net/javascript-hoisting