DEV Community

Sarah Chima
Sarah Chima

Posted on • Originally published at sarahchima.com

What is Hoisting Anyway?

Hoisting is a term you come across from time to time as a JavaScript developer. Do you know what hoisting is and how it works? Well, let us find out if you do. In this article, we will discuss what hoisting is, how it works and what gets hoisted.

What is Hoisting?

To understand what hoisting is, there are some concepts that we need to understand.

First, it is common to think that JavaScript is not a compiled language. Contrarily, the JavaScript engine compiles the code before execution.

Second, we need to understand some types of errors that can occur when we want to fetch the value in a variable. They are the Reference error, Type error and undefined. ReferenceError occurs when you call a variable that is not declared. TypeError occurs when a value is not of expected type. undefined is returned when the variable called has no assigned value or is not initialized. Equipped with this basic knowledge we can now understand what hoisting is. If you do not understand these, examples in this article will help you to understand it better.

So what is hoisting?

Hoisting is a JavaScript concept whereby variable and function declarations are put into memory during the compilation phase before the code is executed. It makes it appear like these declarations are moved to the top of their scope thus making them available anywhere in that scope. Note that this does not physically happen.

Let us understand this better using an example.

console.log(a)

var a = 2;
Enter fullscreen mode Exit fullscreen mode

Looking at the code above, what do you think will be the result? 2? undefined or Reference error? Open your browser console and run the code. What did you get?

I got undefined. I am sure you got that too. You might expect a Reference error because you called a variable before it was declared. That did not happen because the variable declaration was hoisted to the top of the code. So during execution, the code is executed like this.

var a;

console.log(a); //undefined

a = 2;

Enter fullscreen mode Exit fullscreen mode

Makes sense right? Note that it is only declarations that the engine hoists, assignments are not hoisted. Variable declarations are hoisted and initialized with undefined. That is why we got undefined and not 2 because the assignment remained in the place it was assigned.

Also, note that hoisting is per scope. So the variable will be available in the functional scope if we declare within a function. It will be available in the global scope if we declare it outside a function. If we use a variable outside the scope where we declared it, it will return a Reference Error. For example, if we execute the code below, we get a reference error.

console.log(b); //Uncaught ReferenceError: b is not defined

function a() {
    var b = 2
}
Enter fullscreen mode Exit fullscreen mode

Speaking of functions, are all functions hoisted? I think we need a heading for what gets hoisted.

What Gets Hoisted

Function declarations are hoisted. So we can call a function before we declare it in our code.

foo(2); // 2

function foo(a) {
    console.log(a)
}

Enter fullscreen mode Exit fullscreen mode

Function expressions are not hoisted. If we call a function expression before we assign a function to it, we get a TypeError.

foo(2); // Uncaught TypeError: foo is not a function

var foo = function (a) {
    console.log(a)
}

Enter fullscreen mode Exit fullscreen mode

foo is initialized with undefined, therefore calling the variable as a function leads to a type error.

What about ES6 variables let and const? Are they hoisted too?

Yes, they are but are not initialized with undefined like var, they stay uninitialized. If we use them before they we assign a value to them, they return a ReferenceError rather than undefined.

console.log(b); //Uncaught ReferenceError: b is not defined

let b = 2;

Enter fullscreen mode Exit fullscreen mode

Same thing with const

console.log(a);//Uncaught ReferenceError: a is not defined

const a = 2;
Enter fullscreen mode Exit fullscreen mode

We should note that we cannot declare the const variable without initialization. So the code below will throw a different kind of error.

console.log(a)

const a;
a = 4;

//Uncaught SyntaxError: Missing initializer in const declaration
Enter fullscreen mode Exit fullscreen mode

What Gets Hoisted First? Variables or Functions?

We have seen that both variables and function declarations get hoisted. Which of them get hoisted first? Let us do a little exercise. Look at the code below, what do you expect to be printed? string or function? Make a guess and then try it in your console.

console.log(typeof foo);

var foo = 'hello';

function foo() {
    console.log(4);
}

Enter fullscreen mode Exit fullscreen mode

What was the result? I am sure the result is function. This proves two points:

  1. Functions are hoisted first, that is why although the variable was declared before the string, the JavaScript engine still interprets it as a function. In fact, this is how the engine executes the code.
function foo() {
    console.log(4);
}

console.log(typeof foo); //function

foo = 'hello';
Enter fullscreen mode Exit fullscreen mode

If the console.log statement were to come after the variable declaration, the result would have been string instead. Notice that the variable declaration (which is a duplicate of the function ) was ignored. This brings us to the second point.

  1. It is a bad idea to make duplicate declarations with the same variable name. Duplicate declarations are ignored by the JavaScript engine and can often lead to confusing results.

Let us have a review of what we have discussed in this chapter.

Review

  1. Hoisting is a concept where variable and function declaration appears to move to the top of the code during execution. This is because variable and function declarations are processed during the compilation phase.

  2. All variables are hoisted. var is hoisted and initialized with undefined. let and const are hoisted and are not initialized.

  3. Function declarations are hoisted while function expressions are not.

  4. In the compilation phase, functions declarations are hoisted before variable declarations.

Thank you for reading.

Top comments (12)

Collapse
 
ocdalex profile image
Alex Walker

Nicely explained, have bookmarked for future reference.

Collapse
 
sarah_chima profile image
Sarah Chima

Thank you

Collapse
 
inflammatorydev profile image
inflammatorydev

'Note that this does not physically happen.' - THANK YOU! Its refreshing to read a tut on hoisting that explains that the code isnt actually being lifted around the function as so many others do.

Good write up.

Collapse
 
sarah_chima profile image
Sarah Chima

Thank you for your kind words.

Collapse
 
hdennen profile image
Harry Dennen

Useful write up :) The spec has become a lot more reader friendly in recent years too, might be worth a reference tc39.github.io/ecma262/#sec-identi...

Collapse
 
sarah_chima profile image
Sarah Chima

Thanks for sharing the link.

Collapse
 
anshulnegitc profile image
Anshul Negi

why javascript perform hoisting?
As in some cases, we mistakenly define variables or function declarations that are unused throughout the code but due to hoisting it will take all variable and function declarations to memory along with unused variables and function declarations thus slowing the speed of execution.

Collapse
 
ayaanraj profile image
ayaanraj

Great write up, really enjoyed.

Collapse
 
theodesp profile image
Theofanis Despoudis

In other words, what you see is not what you get

Collapse
 
rachanakotha profile image
Rachana Kotha • Edited

Love the way you explain concepts.
Simplicity is the key in your blogs.👏
Expecting more on JS and Frontend related concepts.

Collapse
 
sarah_chima profile image
Sarah Chima

Thank you! :)

Collapse
 
reigningkingforever profile image
Samuel Oluwadamilola Reigningking • Edited

Very simple explanation. .thanks @sarah_chima