Do you really know about Hoisting?

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution. All variable and function declarations are hoisted to the top of their scope

However, in contrast, undeclared variables do not exist until code assigning them is executed. Therefore, assigning a value to an undeclared variable implicitly creates it as a global variable when the assignment is executed. This means that all undeclared variables are global variables.

function hoist() {
a = 20;
var b = 100;
}

console.log(a); // error a is not defined

hoist();

console.log(a); // 20 a becomes global variable
console.log(b); // error b is not defined (it is defined in hoist method scope not global)

All the types var, let and const get hoisted but there is a difference in the default value with which they get hoisted like in var they get hoisted with undefined value but in case of let and const they don't initialize with any value.

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

It will give undefined because only the declaration is hoisted not the initialization. So it will be interpreted as :

var x;
console.log(x);
x = 10;

The same behavior of var is in functional scope also.

function getName() {
console.log(name);
var name = "Max";
}

getName(); // undefined

To avoid this we can declare and define the variable before using it

function getName() {
var name = "Max";
console.log(name);
}

getName(); // Max

As we know in case of let the default value is not there so we cannot access the variable before the engine evaluates its value.

console.log(age); // Output: ReferenceError: age is not defined ...
let age = 25;

So the engine binds the value to the variable where it is actually declared. So if we write code like this

let age;
console.log(age); // undefined
age = 25;

In this case, undefined is printed because as in line 1 we are declaring the variable So we are binding the variable with the value and default value is undefined.

In the case of const. Much like the let keyword, instead of silently exiting with an undefined, the interpreter saves us by explicitly throwing a Reference error.

console.log(age); // Output: ReferenceError: age is not defined ...
const age = 25;

We have to declare and define the const variable together. we cannot separately so that.

const age;  // Missing initializer in const declaration

A function can declassify into 2 parts in terms of hoisting :

Function declaration Function expression

In a function declaration , the function is defined without a new variable like

function print(var name) {
console.log(name);
}

In case of function declaration whole function gets hoisted for example :

print("Alax");  // Alax

function print(var name) {
console.log(name);
}

In this, a function is assigned to a new variable

let printFn = function(var name) {
console.log(name);
}

In this case, only the variable is hoisted not the whole function

printFn();   //Output: "printFn: expression is not a function

let printFn = function(var name) {
console.log(name);
}

printFn is initialized with undefined, it's not a function when we are invoking it that's why we get this error.

Function declarations take precedence over variable declarations. Variable assignments take precedence over function declarations

var name = "Tom";

function name() {
console.log("Harry");
}

console.log(typeof name); // string (variable assignment take precedence)
// 2nd Examplevar name;

function name() {
console.log("Harry");
}

console.log(typeof name); // function (function declaration take precedence)

Hoisting classes are the same as function hoisting. It also has 2 types

Class declarations

Class expressions

Much like their function counterparts, JavaScript class declarations are hoisted. However, they remain uninitialized until evaluation. This effectively means that you have to declare a class before you can use it.

var name = fullName();
name.firstName = "Sourav";
name.lastName = "Ganguly";
console.log(name); // Reference error!!!

class fullName {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}

So we have to declare and define class on top of code where we are using it

class fullName {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}

var name = fullName();
name.firstName = "Sourav";
name.lastName = "Ganguly";
console.log(name); // Output {firstName: "Sourav", lastName: "Ganguly"}

Much like their function counterparts, class expressions are not hoisted.

var name = getFullName();
name.firstName = "Sourav";
name.lastName = "Ganguly";
console.log(name); // TypeError!!! getFullName is not a constructor

var getFullName = class fullName {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
};

Full stack developer