Easy Guide to Hoisting in JavaScript
Introduction
JavaScript has some strange things that can confuse people, and hoisting is one of them. Hoisting means you can use variables and functions before you declare them in your code. But how does this work, and what should you watch out for? In this guide, we’ll explain hoisting in simple terms, so you can understand it better and avoid mistakes.
What is Hoisting?
Hoisting is when JavaScript moves all the variable and function declarations to the top of the code before it runs. However, it only moves the declarations, not the actual values or function code. This can make things behave differently than you might expect.
How Hoisting Works?
Hoisting works differently for var
, let
, const
, and functions. Let's break it down for each one.
Hoisting with var
Variables declared with var
are moved to the top and set to undefined
until the code gets to the line where the value is assigned.
console.log(x); // Output: undefined
var x = 5;
Here’s what really happens:
var x; // `var x` is moved to the top
console.log(x); // It shows `undefined` because the value isn’t assigned yet
x = 5; // The value 5 is given here
So, console.log(x)
shows undefined
because the value assignment happens later.
Hoisting with Functions
Functions are fully hoisted. This means you can call a function even before you write it in the code.
greet(); // Output: Hello!
function greet() {
console.log("Hello!");
}
This works because the whole greet
function is moved to the top.
Hoisting with let
and const
With let
and const
, the variables are moved to the top, but they are not given any value immediately. They are in a "temporal dead zone" (TDZ) until the code reaches the declaration. If you try to use them before their line in the code, you will get an error.
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
So, you can’t use let
or const
variables before you declare them, or you’ll get a ReferenceError
.
Hoisting with Function Expressions and Arrow Functions
Function expressions and arrow functions don't get hoisted like regular functions. If you use var
, let
, or const
to assign a function to a variable, only the variable itself gets hoisted, not the function.
console.log(add(2, 3)); // TypeError: add is not a function
var add = function (a, b) {
return a + b;
};
Here, add
is moved to the top, but not the function part, so calling it before assignment gives a TypeError
.
Hoisting and Block Scope
Hoisting within blocks works differently for var
, which gets hoisted to the top of the enclosing function or global scope, and let
and const
, which get hoisted to the top of their block scope but can't be used before they're declared because of the temporal dead zone.
for (var i = 0; i < 5; i++) {
// ...
}
console.log(i); // Output: 5 (i is accessible outside the loop due to var)
for (let j = 0; j < 5; j++) {
// ...
}
console.log(j); // ReferenceError: j is not defined (j is not accessible outside the loop due to let)
Common Problems with Hoisting
Using variables before they are declared: This is a big no-no, especially with
let
andconst
, because it causes errors.Getting
undefined
withvar
: This happens becausevar
gets moved to the top but doesn't get a value immediately.Mixing up function expressions and function declarations: This can lead to errors if you try to call functions before they are defined.
Tips to Avoid Hoisting Problems
Declare Variables at the Start: Always put your variable declarations at the top to keep things clear and avoid any mix-ups.
Use
let
andconst
Instead ofvar
: They help you avoid hoisting problems and are generally safer.Write Functions Before You Use Them: Even though functions get hoisted, it's a good idea to declare them first.
Avoid Using
var
: Stick tolet
andconst
to keep your code cleaner and avoid unexpectedundefined
values.
Subscribe to my newsletter
Read articles from KodaKodama directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by