JavaScript Hoisting
Last Updated :
20 Mar, 2024
JavaScript hoisting is a mechanism where variable and function declarations are moved to the top of their containing scope during the compilation phase. JavaScript hoisting is a important concept for understanding how variables and functions are processed during code execution. This guide will delve into the features, nuances, and implications of hoisting in JavaScript, covering key topics such as variable declaration, function scoping, and the differences between var, let, and const declarations.
What is Hoisting in JavaScript?
Hoisting is the default behavior in JavaScript where declarations of variables and functions are moved to the top of their respective scopes during the compilation phase. This ensures that regardless of where variables and functions are declared within a scope, they are accessible throughout that scope.
Features of Hoisting
- Declarations are hoisted, not initializations.
- Allows calling functions before their declarations.
- All variable and function declarations are processed before any code execution.
- Undeclared variables are implicitly created as global variables when assigned a value.
Note: JavaScript only hoists declarations, not initializations.
JavaScript allocates memory for all variables and functions defined in the program before execution.
Sequence of variable declaration
The following is the sequence in which variable declaration and initialization occur.
Declaration –> Initialisation/Assignment –> Usage
Variable lifecycle
let a; // Declaration
a = 100; // Assignment
console.log(a); // Usage
However, since JavaScript allows us to both declare and initialize our variables simultaneously, so we can declare and initialize at the same time.
let a = 100;
Note: Always remember that in the background the Javascript is first declaring the variable and then initializing them. It is also good to know that variable declarations are processed before any code is executed.
However, in javascript, undeclared variables do not exist until the 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.
Examples of JavaScript Hoisting
1. Global Scope
Javascript
// Hoisting
function codeHoist() {
a = 10;
let b = 50;
}
codeHoist();
console.log(a); // 10
console.log(b); // ReferenceError : b is not defined
Output:
10
ReferenceError: b is not defined
Explanation: In the above example, hoisting allows variables declared with var to be accessed before declaration, but not those declared with let or const. Thus, a is accessible, but b throws a ReferenceError
Note: There’s a difference between ReferenceError and undefined errors. An undefined error occurs when we have a variable that is either not defined or explicitly defined as type undefined. ReferenceError is thrown when trying to access a previously undeclared variable.
2. JavaScript var hoisting
When we talk about ES5, the variable that comes into our minds is var. Hoisting with var is somewhat different. When it is compared to let/const. Let’s make use of var and see how hoisting works.
Example:
Javascript
// var code (global)
console.log(name); // undefined
let name = 'Mukul Latiyan';
Output:
ReferenceError: Cannot access 'name' before initialization
Explanation: In the above code example variables declared with var are hoisted but not initialized, resulting in undefined when accessed before declaration. Variables declared with let or const do not exhibit this behavior.
But the interpreter sees this differently, the above code is seen like this:
Javascript
// how interpreter sees the above code
let name;
console.log(name); // undefined
name = 'Mukul Latiyan';
3. Function scoped variable
Let’s look at how function-scoped variables are hoisted.
Example:
Javascript
// Function scoped
function fun() {
console.log(name);
let name = 'Mukul Latiyan';
}
fun(); // Undefined
Output:
undefined
There is no difference here as when compared to the code where we declared the variable globally.
Example: We get undefined as the code seen by the interpreter.
Javascript
function fun() {
let name;
console.log(name);
name = 'Mukul Latiyan';
}
fun(); // undefined
In order to avoid this pitfall, we can make sure to declare and assign the variable at the same time, before using it.
Example:
Javascript
function fun() {
let name = 'Mukul Latiyan';
console.log(name); // Mukul Latiyan
}
fun();
4. JavaScript hoisting with Let
We know that variables declared with let keywords are block scoped not function scoped and hence there is no problem when it comes to hoisting.
Example:
Javascript
//let example(global)
console.log(name);
let name = 'Mukul Latiyan'; // ReferenceError: name is not defined
Output:
ReferenceError: name is not defined
Explanation: Like before, for the var keyword, we expect the output of the log to be undefined. However, since the es6 let doesn’t take kindly on us using undeclared variables, the interpreter explicitly spits out a Reference error. This ensures that we always declare our variable first.
5. JavaScript hoisting with const
It behaves similarly to let when it comes to hoisting. A function as a whole can also be hoisted and we can call it before the declaration.
Example:
Javascript
fun(); // Calling before declaration
function fun() { // Declaring
console.log("Function is hoisted");
}
OutputFunction is hoisted
Also, if a function is used as an expression and we try to access it before the assignment an error will occur as only declarations are hoisted.
Example:
Javascript
fun() // Calling the expression
let fun = () =>{ // Declaring
let name = 'Mukul Latiyan';
console.log(name);
}
Output:
ReferenceError: Cannot access 'fun' before initialization
However, if var is used in the expression instead of let we will get the following Type Error as follows.
6. Hoisting with Functions
Example:
Javascript
fun() // Calling the expression
var fun = () =>{ // Declaring
let name = 'Mukul Latiyan';
console.log(name);
}
Output:
TypeError: fun is not a function
Share your thoughts in the comments
Please Login to comment...