JavaScript Hoisting 

Author:

When it comes to programming languages, each differs either in the type of functionalities they provide or by their fundamentals like syntax, variable and function declaration, definition, and many more. In JavaScript, there is one unique feature that most developers ignore, yet it is one of the unique and interesting features offered by the scripting language. Let’s look into what JavaScript hoisting is and how exactly it is advantageous to programmers:

What is JavaScript Hoisting? 

Let’s start with an example:

Whenever you start writing a program, you will first declare the variable before assigning a value to it.

Example:
var counter = 1;
console.log(counter);

This is how the declaration of variables is made in most languages, but there is a slight twist when it comes to declaring functions and variables in JavaScript.

By twist, we are not implying that the above example does not work in JavaScript.

What we are trying to say is, look at the following example:

Example:

In the following example, the variable ‘counter’ is used before it is defined.

console.log(counter); // undefined
var counter = 1;

Imagine the above scenario in other programming languages; the compiler would return an error warning saying that the variable is used before definition. In the case of JavaScript, however, the preceding code works perfectly. This is due to JavaScript’s one-of-a-kind feature known as hoisting.

In JavaScript, when the code is finally at the execution phase, every declaration statement is moved to the top of the scope. This process is known as hoisting.

Programmers can define variables and functions wherever they want without worrying about errors thanks to the hoisting.

Following hoisting the declarations, JavaScript proceeds to allocate memory to all the variables and functions before execution.

Why Does Javascript Hoist Variables and Functions?

JavaScript does not have a specific justification or definition for hoisting variables and functions.

Hoisting may be an unprecedented behaviour by the interpreter because the interpreter works in two phases:

  • Code completion/compilation.
  • Code execution.

The interpreter goes through all the variable and function declarations in the first phase.

In the second phase, the actual execution step begins where the interpreter processes the function expressions and undeclared variables.

So maybe for a more unambiguous interpretation, the JavaScript interpreter performs hoisting.

According to Brendan Eich, the founder of JavaScript, “var hoisting was thus an unintended consequence of function hoisting, no block scope, JS as a 1995 rush job.”

Types of Javascript Hoisting

JavaScript offers two types of hoisting:

  • Variable hoisting, where the variables moved to the top.
  • Function hoisting, where the function declarations are transferred to the top.

Another critical point to note is that JavaScript only hoists the declarations, not the initialisations.

JavaScript Variable Hoisting

As we mentioned earlier, JavaScript hoists the variable declaration to the top of the script in variable hoisting.

To explain the concept of variable hoisting in more detail, let’s look into the following example:

Example:

In the following example, we are declaring the variable ‘a’ after it’s been assigned to do a task:

console.log(a); // undefined
var a = 1;

The code does not return any error in the above example because the engine hoists the declaration to the top of the script while initiating the execution phase.

To explain more clearly, during the execution phase, the above coding will appear to the interpreter as follows:

Example:
var a;
console.log(a); // undefined
a = 1;

From the preceding example, the JS engine has only pushed the declaration part to the top, despite the fact that the variable is assigned a specific value. This emphasises the fact that hoisting is only helpful for declarations and not for initialisations.

While the execution phase, the value of the variable is undefined. This is because the default declaration of var is undefined. 

So the output of the above example will be ‘undefined’.

So, how will you get the assigned value of ‘a’ as the output?

Through the following code:

var a;
console.log(a); // undefined
a = 1;
console.log(a); // Returns 1 after the line with initialization is executed.

Now the above code will execute the assigned value.

By comparing the two examples, we hope you get a clear understanding of what we meant by hoisting only moves declarations to the top and not initialisations.

Another Example:

Since it is not necessary to use ‘var’ to declare a variable in JavaScript, you may consider the possibility of whether hoisting works on variables declared without using ‘var’; let’s clear your confusion with the following examples:

console.log(a); // Throws ReferenceError exception - the interpreter doesn't know about `a`.
a = 6; // Initialization

If the variable is not declared but initialised after the usage, hoisting will not work, and the interpreter will return the ReferenceError exception.

But the same example will work if the initialisation is done before the usage as follows:

a = 6;
console.log(a);

The above code snippet will execute the value of ‘a’ even though it is not hoisted because we have declared the variables before the function.

The let and const keyword

Similar to var, variables are also declared with let and const in JavaScript.

  • The let keyword can be updated but not be redeclared into the scope.
  • The const keyword neither can be updated nor redeclared into the scope.

Another similarity between let and const is that they cannot be declared without initialising. Note this point since it is essential to understand how hoisting differs when working with var, let, and const keywords.

Example with let keyword:

In the upcoming example, we declare the variable a with the keyword let.

console.log(a);
let a = 1;

The above code will return:

ReferenceError: Cannot access 'a' before initialization

From the error statement, the interpreter lets us know that the above variable exists in its memory but not its variable.

But the above scenario worked with the var keyword. Why?

Our point is that the let keyword is not initialised with any default value. So even though JavaScript hoists variable declaration using let keyword, it does not initialise the variables.

Also, note that the error statement received in the above example notifies that only the initialisation is not defined. 

If the variable does not exist, look at the following code for answers:

Example:
console.log(b);
let a = 1;

The error statement will be:

ReferenceError: b is not defined

Similarly, the const keyword that does not have any default value to be initialised will return an error even when hoisted; if not, the variables are declared before the usage.

JavaScript Function Hoisting

Similarly to how variables are hoisted, functions declared after the function definition are hoisted to the top of the script, and no errors are caused by doing so.

So let’s look into a small example using functions to know how to function hoisting works in JavaScript:

Example:

In this example, we have used the ‘sum’ function before defining it:

Code before execution:
let x = 20,
  y = 10;
let result = sum(x, y);
console.log(result);
function sum(a, b) {
  return a + b;
}

During the execution phase, the interpreter hoists the ‘sum’ method to the top of the scope, and it will seem as follows:

Code during execution:
function sum(a, b){
    return a + b;
}
let x = 20,
    y = 10;
let result = sum(x,y);
console.log(result);

The JavaScript engine places the sum() function declaration in the heap memory during the execution phase. In other words, the engine creates an object of the Function type and a function reference called sum that refers to the function object.

Now, we know function can be hoisted.

Precisely, function declarations can be hoisted, not function expressions. Here is another example that will explain clearly:

Example:

In this example, the function sum is not declared as a function but a function expression.

let x = 20,
    y = 10;
let result = sum(x,y);
console.log(result);
var sum = function(x, y) {
return x + y;
}

The output for the code will be an error statement:

TypeError: sum is not a function

This is because, during the execution phase, the variable sum, which is declared using the keyword let, is initialised and its default value undefined.

Like function declarations, the class declaration can also be hoisted in JavaScript. However, we recommend you not rely on it because the class does not get initialised on default. So if you declare class after the definition, it will result in the engine throwing ReferenceError.

Word of Caution:

JavaScript hoisting is not a reliable feature, and we recommend you follow the traditional way of declaring variables and functions before using them. Though relying on hoisting is quite handy, misusing it can cause errors, so make sure you understand hoisting well before you depend on it.

Wrapping Up 

We hope you understand how JavaScript hoisting works and how to rely on them while programming. As applicable this feature might be, thorough knowledge and practice are necessary to make the fullest of JavaScript hoisting. So practice JavaScript hoisting suing the above examples, and master the unfamiliar concept.

New to JavaScript?

If you’re new to JavaScript, then it’s time to learn some of the basics. Register for our free 5 Day Coding Challenge through the form below and learn the basics of HTMLCSS and JavaScript. Alternatively, if you want to go deeper into coding, then read more about our Full Stack programme here.

What is an AI Developer & How to Become One?

Right now, the world is witnessing an artificial intelligence technological revolution, and AI Developers are at the forefront. AI developers are those who design, develop, and deploy AI-powered solutions. They are shaping the technological future by creating intelligent systems and applications. We look into the world of AI developers, exploring their roles, skills, and the […]

Systems Analyst: A Guide 

A system analyst looks after a company’s computer systems and network and ensures they meet its goals. They ensure that the infrastructure, computers and other systems work efficiently.  Who do you think takes care of all the systems in a company and plans everything out for a firm to meet its needs? Who do you […]

What Does a .NET Developer Do & How to Become One?

.NET developers are essential in the realm of software development. They are in charge of planning, creating, testing, and managing software applications built with the Microsoft .NET framework. As a result, they are in high demand and can command substantial wages in the tech business. In this blog, we will look at what a .NET developer […]