DEV Community

Cover image for Hoisting in JavaScript
Nozibul Islam
Nozibul Islam

Posted on • Edited on

Hoisting in JavaScript

What Hoisting is a JavaScript?

Hoisting refers to the process in JavaScript where declarations are made before execution. Variable and function declarations are processed first. As a result, even if a variable is referenced before its declaration, it will not cause an error, but instead return undefined. For function declarations, the entire function is hoisted, meaning it can be used before it is defined in the code. This process places the declarations into the stack before the execution starts.

In simpler terms:

  • Variables declared with var are initialized as undefined during hoisting.

  • Function declarations are fully hoisted and can be called before they are written in the code.

  • The hoisting process ensures that these declarations are recognized in the execution stack, regardless of their position in the code.

It’s important to note that only declarations are hoisted, not the assignments. The assignments stay at the same place where you wrote them.

Note: Those who say that during hoisting the code moves to the top are actually wrong. The code never moves up.

Example:

console.log(myVariable); // undefined      
var myVariable = 10;
Enter fullscreen mode Exit fullscreen mode

This code performs two actions simultaneously. First, it declares the variable myVariable and hoists it to the scope, but its value is still undefined. Therefore, the console.log command displays the uninitialized value as undefined. After that, the value 10 is assigned to myVariable.

However, if you try to change it, it won’t have any effect on the previous declaration. For example:

console.log(myVariable); // ReferenceError: myVariable is not defined      
myVariable = 10;
Enter fullscreen mode Exit fullscreen mode

Here, we haven’t declared the myVariable variable, so it throws a ReferenceError before attempting to change it.

In summary, JavaScript reads all the code first and then hoists all the declarations to the out while keeping the assignments in their original positions. This process is known as hoisting.

var and let are also hoisted :

Both var and let are hoisted in JavaScript, but their behavior is slightly different.

var:

When you declare a variable using var, its declaration is hoisted to the out of the scope, and you can access the variable before its declaration, but it will have the value undefined until it is assigned a value.

Example:

console.log(myVariable); // undefined
var myVariable = 10;
Enter fullscreen mode Exit fullscreen mode

In the above code, the declaration var myVariable is hoisted to the out of the scope, but the assignment myVariable = 10 is left in place. Therefore, the console.log statement outputs undefined because the variable exists but has not been assigned a value yet.

let:

On the other hand, when you declare a variable using let, the hoisting behavior is a bit different. The variable declaration is hoisted, but you cannot access the variable before its declaration. This is known as the "temporal dead zone." If you try to access a let variable before its declaration, you will get a ReferenceError.

Example:

console.log(myVariable); // ReferenceError: myVariable is not defined
let myVariable = 10;
Enter fullscreen mode Exit fullscreen mode

In this case, the let the declaration is hoisted, but the variable cannot be accessed before its declaration. Therefore, the console.logstatement throws a ReferenceError because the variable has not been defined yet.

Here basically in the case of let, even if hoisted up, the value of the variable remains undefined. Because there is no space in memory for that variable. Because of this cannot refer to that address. Because there is no address of myVariable = 10 in the memory, it gives a reference error.

const:

The const keyword allows you to create constants, which are variables that cannot be reassigned once a value is assigned to them.

Example:1

const PI = 3.142;
PI = 22/7; // Attempt to reassign the value of PI
console.log(PI); // Output: TypeError: Assignment to constant variable

Enter fullscreen mode Exit fullscreen mode

In this example, we define PI it as a constant with an initial value of 3.142. When we try to reassign a new value to PI, a TypeError is thrown because constants cannot be reassigned.

Example:2

const PI;
console.log(PI); // Output: SyntaxError: Missing initializer in const declaration
PI = 3.142;
Enter fullscreen mode Exit fullscreen mode

In this case, we declare a constant PI without initializing it. This code throws a SyntaxError because constants must be declared and initialized at the same time.

Example:3

function getCircumference(radius) {
  console.log(circumference);
  circumference = PI * radius * 2;
  const PI = 22/7;
}
getCircumference(2); // ReferenceError: circumference is not defined
Enter fullscreen mode Exit fullscreen mode

Here, within the getCircumference function, we try to access circumference it before its declaration. It throws a ReferenceError because the variable is not defined yet.

When using const, it is necessary to declare and initialize the variable before using it.

Overall, var and let are both hoisted in JavaScript, but their behavior and the concept of the temporal dead zone apply only to let variables. const creates constants that cannot be reassigned once initialized.

All undeclared variables are global variables:

function hoisted() {
a = 20;
var b = 100;
}
hoisted();
console.log(a); // 20
// can be accessed as a global variable outside the hoisted() function.

console.log(b);
// As it is declared, it is bound within the bounds of the hoisted() function. We cannot print it outside the hoisted() function.
output: ReferenceError: b is not defined
Enter fullscreen mode Exit fullscreen mode

Function scoped variables

We can see that the declaration of the var message variable in the scope of the function hoist() is going to the top of the function.
To avoid this problem, we’ll make sure we declare the variable before we use it.

In both examples you provided, the output will be undefined.

Example:1


function hoist() {
  console.log(message);
  var message = 'Hoisting is all the rage!';
}
hoist(); // Output: undefined
Enter fullscreen mode Exit fullscreen mode

Example:2

function hoist() {
  var message;
  console.log(message);
  message = 'Hoisting is all the rage!';
}

hoist(); // Output: undefined
Enter fullscreen mode Exit fullscreen mode

In both cases, the output is undefined because the variables are hoisted to the top of their respective scopes but their assignment occurs afterward in the original order of the code.

Function expressions

Function expressions are not hoisted, and throw a TypeError because the expression is treated as a variable and not as a function.

expression(); // Output: "TypeError: expression is not a function
var expression = function() {
  console.log('Will this work?');
};
Enter fullscreen mode Exit fullscreen mode

Strict Mode

From its name, it is a restricted variant of JavaScript that will not tolerate the usage of variables before they are declared. Running our code in strict mode:

  • Eliminates some silent JavaScript errors by changing them to explicit throw errors.

  • Fixes mistakes that make it difficult for JavaScript engines to perform optimizations.

  • You may be missed out on declaring the variable, use strict which has stopped you by throwing a Reference error.

'use strict';

console.log(hoist); // Output: ReferenceError: hoist is not defined
hoist = 'Hoisted';
Enter fullscreen mode Exit fullscreen mode

Conclusion

It is important to understand hoisting in JavaScript when declaring variables and functions, as hoisting is explained, you will understand how the JavaScript code is actually being handled.

🔗 Connect with me on LinkedIn:

I regularly share insights on JavaScript, Node.js, React, Next.js, software engineering, data structures, algorithms, and more. Let’s connect, learn, and grow together!

Follow me: Nozibul Islam

Top comments (0)