Hoisting is a fundamental concept in JavaScript that often leads to confusion, especially for those new to the language. Understanding how hoisting works can help you write cleaner and more predictable code.
This article explains what hoisting is, how it works, and the differences in behavior between various types of declarations.
What is Hoisting?
Hoisting is JavaScript’s default behavior of moving declarations to the top of their scope before code execution. This means that variables and functions can be referenced before they are declared in the code.
It is important to note that only declarations are hoisted, not initializations.
Variable Hoisting with var
Variables declared with var
are hoisted and initialized with undefined
. Consider the following example:
console.log(a); // undefined
var a = 10;
Internally, this is interpreted as:
var a;
console.log(a); // undefined
a = 10;
The declaration var a;
is hoisted to the top, while the initialization a = 10;
stays in place.
Hoisting with let
and const
Variables declared with let
and const
are also hoisted, but they are not initialized. Accessing them before the declaration results in a ReferenceError
due to the Temporal Dead Zone (TDZ)—the time between entering the scope and the actual declaration being encountered.
console.log(b); // ReferenceError
let b = 20;
Unlike var
, let
and const
declarations are block-scoped and do not allow access before their declaration line.
Function Hoisting
Function declarations are fully hoisted, meaning you can call the function before it is defined:
greet(); // "Hello, world!"
function greet() {
console.log("Hello, world!");
}
Function expressions, however, are treated like variables. Only the variable name is hoisted, not the function definition.
sayHello(); // TypeError: sayHello is not a function
var sayHello = function () {
console.log("Hello");
};
Here, sayHello
is hoisted and initialized as undefined
, which causes an error when called as a function.
Summary of Hoisting Behavior
Declaration Type | Hoisted | Accessible Before Declaration | Notes |
---|---|---|---|
var |
Yes | Yes, but value is undefined
|
Function-scoped |
let |
Yes | No | Block-scoped, TDZ applies |
const |
Yes | No | Block-scoped, TDZ applies |
Function Decl. | Yes | Yes | Entire function is hoisted |
Function Expr. | Yes | No | Treated like var
|
Best Practices
- Use
let
andconst
instead ofvar
to avoid hoisting-related issues. - Declare variables and functions at the beginning of their respective scopes to make the code more readable and less error-prone.
- Avoid using variables before declaring them, even if hoisting makes it technically possible.
- Be cautious with function expressions, especially when defined with
var
.
Conclusion
Hoisting is a key aspect of JavaScript’s execution model. While it can be unintuitive at first, understanding how JavaScript handles variable and function declarations will help you avoid common pitfalls. Write your code with clarity and always declare variables and functions before using them.
Top comments (4)
In Wat I know I don't think weather let and const are hoisted, only vars are hoisted
let and const are hoisted but not as var as they are not initialized and cannot be accessed until their declaration is evaluated, due to the Temporal Dead Zone (TDZ), which helps prevent bugs from accessing variables before declaration.
Understood, thanks
my pleasure