This is going to be the second quesion of the front-end interview quesion series. If you want to check the first one click here .

Hoisting

Hoisting is a very important concept of JavaScript which can introduce bug or cause unexpected behavior in your code if you’re not aware of how it works.

JavaScript Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables, classes, or imports to the top of their scope, prior to execution of the code. –MDN

Example

// 1st Example
console.log(name); // Output: undefined
var name = "shahzaib";

//2nd Example
log(); // Output: Hello world!

function log() {
  console.log("Hello world!");
}

When the JavaScript engine executes the JavaScript code, it creates the global execution context. The global execution context has two phases:

  1. Creation
  2. Execution

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

Variable Hoisting

In JavaScript, you can declare variables using either var, let, or const. These variables will be hoisted, but they behave differently.

When you declare the variable using var keyword, the declaration of a var variable is automatically moved to the top of its respective scope (global or function) at runtime:

// global scope
console.log(test); // undefined <-- HOISTING
var test = 40;
console.log(test); // 40

function foo() {
  // function scope
  console.log(test); // undefined (not 40) <-- HOISTING
  var test = 45;
  console.log(test); // 45
}

foo();
console.log(test); // 40


The let and const were introduced in ES6 version of JavaScript for declaring the block-scope variables and constants

// global scope
console.log(test); // ReferenceError
let test = 40;
// global scope
console.log(test); // ReferenceError
const test = 40;

At first sight, you might think that the let and const keywords are not hoisted, and thrown the Reference error, but it’s false.

Variables those are declared using let and const are also hoisted (they moved to the top of their respective scope) but not initialized with a default value. The reason of the ReferenceError is a temporal dead zone (A temporal dead zone (TDZ) is the block where a variable is inaccessible until the moment the computer initializes it with a value.)

Function Hoisting

Look at this code snippet.

add(); // Output: 10

function add() {
  const sum = 5 + 5;
  console.log(sum);
}

Here, we ran add function before declaration of the add function. And everything works fine without any errors because of Hoisting

Before the interpreter executes the whole code, it first moved the declared function to the top of the scope it is defined in. In this case, add is defined in the global scope, so the function is hoisted to the top of the global scope. Through hoisting, the function (including the logic) becomes accessible even before the line it was declared in the code.

Function expressions are not hoisted:

logger1(); // Output:  TypeError: logger1 is not a function
logger2(); // Output: ReferenceError: Cannot access 'logger2' before initialization
logger3(); // Output: ReferenceError: Cannot access 'logger3' before initialization

// Function expression using var
var logger1 = function () {
  console.log("logger 1");
};

// Function expression using let
let logger2 = function () {
  console.log("logger 2");
};

// Function expression using const
const logger3 = function () {
  console.log("logger 3");
};


If you find this helpful please share with your network ✅.

Happy Coding 🙌 !