Hoisting in JavaScript
Hoisting is a behavior in which variable and function declarations are moved (or "hoisted") to the top of their containing scope (either the global scope or function scope) before the code is executed. This means that you can use variables and functions before they are actually declared in the code.
Hoisting in Variables
var
- Variables declared with
var
are hoisted to the top of their scope, but their values are not initialized until the point in the code where the assignment occurs.
console.log(x); // undefined
var x = 5;
console.log(x); // 5
let
and const
- Variables declared with
let
andconst
are also hoisted but are placed in a "temporal dead zone" until their declarations are reached. Accessing them before they are declared will result in aReferenceError
.
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
// block scope
{
let x = 5;
}
console.log(x); // ReferenceError: x is not defined
Hoisting in Functions
Traditional Function
- Function declarations are fully hoisted, meaning both the declaration and the function body are moved to the top of the scope. This allows you to call a function before its declaration in the code.
sayHello(); // "Hello!"
function sayHello() {
console.log("Hello!");
}
- In contrast, function expressions (where a function is assigned to a variable) are only hoisted as variables, so calling them before the variable is initialized will result in
undefined
or aTypeError
.
greet(); // TypeError: greet is not a function
var greet = function () {
console.log("Hi!");
};
greet(); // ReferenceError: Cannot access 'one' before initialization
let greet = function () {
console.log("Hi!");
};
Arrow Function
- In contrast, function expressions (where a function is assigned to a variable) are only hoisted as variables, so calling them before the variable is initialized will result in
undefined
or aTypeError
.
greet(); // TypeError: greet is not a function
var greet = () => {
console.log("Hi!");
};
greet(); // ReferenceError: Cannot access 'one' before initialization
let greet = function () {
console.log("Hi!");
};
Temporal Dead Zone (TDZ)
The temporal dead zone (TDZ) exists for variables declared using let
and const
because JavaScript is designed to prevent you from accessing these variables before they are declared and initialized.
Why var
and let
, const
behave differently in hoisting
- It is because of the historical evolution in JavaScript.
- Initially, JavaScript was designed for users who are not developers, and the main core usage of JavaScript was to add small interactive elements to the webpage.
- So
var
supports only functional scope. Also at that time, there was no block scope. - But in the later evolution of JavaScript, it became more complicated to work with
var
and fix bugs. - So to make JavaScript competitive with other modern languages, more features were added like
let
,const
, arrow functions, ES6 methods, etc.
Why var
is not updated like let
and const
- It is because of backward compatibility.
- At that time, JavaScript was widely used by many enterprises, so updating or making changes in existing features would lead to breaking the codebase.
- Therefore, modern features were added individually.
Common Interview Questions
- What is hoisting in JavaScript?
- What is hoisted in JavaScript, and what is not?
- What’s the difference between
var
,let
, andconst
with respect to hoisting? - What is the temporal dead zone (TDZ) in JavaScript?
- Can you explain hoisting with function declarations vs. function expressions?
- What is hoisting in ES6 modules?
- Why should we avoid relying on hoisting in real-world code?
Summary
- Hoisting is the default behavior in JavaScript where variable and function declarations are moved to the top of their respective scopes during the compilation phase.
- Hoisting works only for variables declared with
var
and traditional functions, not forlet
,const
, and arrow functions. - Only the function declaration is hoisted, so traditional functions work, but if the function is assigned to a variable, it will not be callable until it is defined.
- The reason why
var
and traditional functions are hoisted butlet
,const
, and arrow functions are not is because at the initial stage, JavaScript was mostly used for small UI interactions. - But later, as JavaScript was widely used for building applications by enterprises, it became harder to fix bugs with just global scope.
- So in future updates, more secure concerns were addressed.
- Additionally, updating existing features would have broken codebases, so new features were added separately.
Top comments (5)
our post is very informative and clear. It will be helpful for newcomers to understand how hoisting works. The examples are well-analyzed, especially the discussion on variable and function hoisting. I hope to read more of your valuable insights on important topics in the future!
Thank you for your kind words! I'm glad to hear that you found the article informative and helpful.
welcome.
What are the benefits of hoisting?
Hoisting provides flexibility in accessing functions and variables. But it may lead to many bugs, so proper understanding and usage of hoisting helps in debugging.