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;
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;
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
}
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)
}
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)
}
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;
Same thing with const
console.log(a);//Uncaught ReferenceError: a is not defined
const a = 2;
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
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);
}
What was the result? I am sure the result is function
. This proves two points:
- 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';
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.
- 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
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.
All variables are hoisted.
var
is hoisted and initialized withundefined
.let
andconst
are hoisted and are not initialized.Function declarations are hoisted while function expressions are not.
In the compilation phase, functions declarations are hoisted before variable declarations.
Thank you for reading.
Top comments (12)
Nicely explained, have bookmarked for future reference.
Thank you
'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.
Thank you for your kind words.
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...
Thanks for sharing the link.
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.
Great write up, really enjoyed.
In other words, what you see is not what you get
Love the way you explain concepts.
Simplicity is the key in your blogs.👏
Expecting more on JS and Frontend related concepts.
Thank you! :)
Very simple explanation. .thanks @sarah_chima