What is Hoisting in JavaScript?

What is Hoisting in JavaScript?
Have you ever came across the term “Hoisting” when you started learning JavaScript?
For the most of interviewer it has been their favorite question for them. They just want to know if the person sitting right in-front of him have any idea about “Hoisting” and if the person nodded his/her head with yes. They start playing trick on them.
Here we Go…
So what the heck is hoisting?
If you ask this question to any JavaScript developer. He/She will answer you with one of two definitions.
Hoisting means When JavaScript compiler treats your codes in such way that all the variable declarations using var are hoisted/lifted/moved
1. To the top of their functional/local scope if declared inside a function
2. To the top of their global scope if declared outside of a function regardless of where the actual declaration has been made
Now the another definition of hoisting could be
At the time of JavaScript compilation phase, all the function and variable declarations done in the code are added to memory.
if this happens, we could use our function or variable before it has been declared.
If you go through those above definitions, we have talked hoisting with regards to variable and function.
That means, we have two type of hoisting here
1. Variable hoisting
2. Function hoisting
Lets go one by one ..
Variable Hoisting
Enough talking! Lets jump on to some examples for better understanding.
example:1
var name = “Rohit”; 
console.log(name); //Output: Rohit
In the example 1, we all know what the result would be as “name” is already initialized in the first place with “Rohit” and then we are logging it on the console.
example: 2
name = "Rohit";
console.log(name);
var name;
//output: Rohit
                    
In the example, it is pretty clear that we have assigned a string to variable name and then we logged on the console and at last we have declared it.
Everything is fine till now.
Lets try example: 3
console.log(name);
var name = "Rohit";
//Output: undefined
                    
When i was new to hoisting concept, running this last example really surprised me as I was expecting that the output will be "Rohit".
but the moment I understood the real meaning of hoisting, no longer it surprised me
In the example 1, 2 and 3, hoisting played its good role but what really happened with the example 3 is this. Take a look on below code.
var name;
console.log(name)
name = "Rohit";
//output: undefined
                    
Now it was obvious that the result would be undefined.
And this is how JavaScript treat your code when it finds situations like example 3 .
According the above definitions, our defined variables with var keyword moved to their top of the scope which is here global in this case.
Now what about value we assigned to the variable name.
Note: In the Hoisting, only variable declarations get moved to the top of scope, not the actual value which is assigned to the variable.
JavaScript only hoists declarations. Initialization and Assignment are not hoisted.
Now we all know the reason for the above example 3 scenario.
Now what about Block Level Declaration (ES6) (within curly braces {})
Let’s talk about another level of declaration.
We have been talking about variable declaration using var keyword.
Other than var, we have another two keywords to declare variables
let & const
Note: let and const also participate in hosting but in quite different way.
Until ES5 we did not have block level scoping and so all the variables declared inside a block are always hoisted to function level scoping.
What does scoping really mean?
We can say like that, Scope refers to visibility of your declared variables inside your program, which determines where you are allowed to use variables you have declared earlier
ES6 introduces Let variables which comes up with block level scoping feature which provide developers with more control and flexibility while dealing with variable in your programs
How many scopes do we have?
we have global scope,function scope and try/catch scope, with ES6 we also get the block level scoping by using Let.
So that means, if we use let keyword, we can create a new scope without even using a function and those variables will only be available in block code {}
Lets take a look on below example
let a = 6; // here variable a has global level scope
function joinMe () {
let a = 10; //variable a has function level scope
console.log(a); // 10
if(a) {
let a = 11; //variable a has it own if block scope
console.log(a); // 11
 }
console.log(a); //10
   }
joinMe();
console.log(a); // 6;
                    
Re-declaring the same variable within the same function or block scope using let & const is not allowed in JavaScript.
//in this case, the variable "arg" re-declares the argument.
function foo(arg) { 
     let arg = 'foo'; 
  }
foo(6);//Uncaught SyntaxError: Identifier 'arg' has already been declared
function foo(arg) { 
 const arg = 'foo'; 
  }
foo(6); // Uncaught SyntaxError: Identifier 'arg' has already been declared
But It does not effect var
function foo(arg) { 
  var arg = 'foo'; 
}
foo(6); //No Error
If you want change the received argument just omit the let/const keyword
function foo(arg) { 
  arg = 'foo'; 
}
foo(6); //No Error
Take a look here
let name = "Mohit";
let name = "Rohit"; //  Uncaught SyntaxError: Identifier 'name' has already been declared
var name = "Xyz" // Uncaught SyntaxError: Identifier 'name' has already been declared
const name = "Constant"; // Uncaught SyntaxError: Identifier 'name' has already been declared

function Check() {
let  x = 6;
let x = 7;//  Uncaught SyntaxError: Identifier 'x' has already been declared
var x = "QWER"; //Uncaught SyntaxError: Identifier 'name' has already been declared
const x = "X" //above error
if(x) {
const x = 55; //no error
var x = 8 //Uncaught SyntaxError: Identifier 'x' has already been declared
let x = 9 // No error
const x = 11; //No error
}
}
Check();
well, you can see the 2nd error statement unless you resolve the first one.
The main use of const keyword is to declare a variable with read-only named constant in block-scoped and therefore they cannot be re-assigned values once defined.every const declaration must be initialized at the time of declaration.
The best practice is to use let for variable declaration, being block scoped, it does not affect the outer scope variable of same name declared using let. Avoid using var and start using let and const per function.
let x = 7;
for(let x = 0; x < 5; x++) {
let y = x; //0 to 4
}
console.log(x); //7
Since Block level declaration are made under block scope or lexical scope.
Lets deals with the term Lexcial scoping.
Lexical Scope or Static Scope
Since, it is very important and powerful concept, we need to understand the base concept of this scope
Lexial scoping or static scoping sets the scope (range of functionality) of a variable so, that it may only be called (referenced) from within the block of code in which it is defined. The functions refers the variable in the context where it was defined regardless of surrounding variables. The scope is determined when the code is compiled or
Lexically scoped variables are available (or) accessible at the local level of the function in which it was defined.
Lexical scoping powers JavaScript closure functionality.
To understand it better, take a look on below code
var data = "Global"
function  outerFunction() {
  var data  = "Outer";
  
  function innerFunction() {
    return data;
  }
  return innerFunction;
}
console.log(outerFunction()()); //Outer
If you see the above code, we have one outerFunction and inside it, we have one more function innerFunction which is returning the outer function data. The inner function is returned at last.
If we call the outer function, it will output the variable data which is defined in the outer one. That means, even the inner function has been returned, it is able to access its outer function data.
Every inner level function can access its outer level function data
OR
Inner functions contain the scope of parent functions even if the parent function has returned.
The inner function still preferring the variable data in context with place it was defined. Lexical scoping are helpful in defining how variable are resolved in nested functions.
Function Hoisting
I am not sure if you know, but function hoisting is quit different than variable hoisting in JavaScript which we saw earlier.
Have you ever call function in the below patters
sayHello(); //Hello There!
function sayHello() {
console.log("Hello There!");
}
How we called the function before we defined?
Yes you are right! This is function hoisting.
How JavaScript interpret your code is
function sayHello() {
console.log("Hello There!");
}
sayHello(); //Hello There!
This is behavior can be seen for both, function declaration in the Global scope or functional scope which is also known as local scope.
As we know we can create function in two ways in JavaScript.
1. with using function declaration.
2. with function expression.
The reason for discussing above points are just to clear that
Hoisting are not applicable on function created with expression
Because we could not call the expression function before declaring it.
sayHello(); //  Uncaught ReferenceError: sayHello is not defined
const sayHello = () => {
console.log("Hello There!")
}
Have you ever heard, function hoisting are move to top of the scope than the top scope of variable
Lets prove this point.
var say = "Hello";
function Hey() {
  say = "Hi";
  return ;
  function say() {}
}
Hey();
console.log(say); //Hello
I know you were expecting the output to be “Hi” since you found that we are overwriting the global say variable. But that is not the case.
JavaScript looks on it with a different eye and here what it is
var say = "Hello";
function Hey() { 
//Hoisted at top
 function say() {} //this created local scope say variable
  say = "Hi"; //changing local a from function to integer
  return ;
}
Hey();
console.log(say); //Hello
Since the inner say() function got hoisted at top, it created a local say which is then converted from function to integer with say=”Hi” assignment.

Thanks for reading this article. I hope you have enjoyed this.

People Reaction : 0

Rohit Sharma
Name : Email : Website :
© 2020 WriteSomeCode. All Right Reserved. A Rohit Sharma Blog. Creative Commons License licensed under a Creative Commons Attribution 4.0 International License