Hoisting in JavaScript is a behavior where variable and function declarations are moved to the top of their containing scope during the compile phase, while the actual assignments remain in place. This means that regardless of where variables and functions are declared in your code, they are effectively moved to the top of their scope.
Hoisting with var, let, and const
Before diving into const specifically, let's understand how hoisting works with var and let.
Hoisting with var:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hoisting with var</title>
</head>
<body>
<script>
console.log(age); // Output: undefined
var age = 30;
console.log(age); // Output: 30
</script>
</body>
</html>
In this example, the console.log(age) statement before the variable declaration doesn't throw an error but outputs undefined. This is because the declaration of var age = 30; is hoisted to the top, but the assignment (= 30) remains in place.
Hoisting with let:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hoisting with let</title>
</head>
<body>
<script>
console.log(age); // Error: Cannot access 'age' before initialization
let age = 30;
console.log(age); // Output: 30
</script>
</body>
</html>
With let, the behavior is different. Trying to access the variable before its declaration results in a ReferenceError. This is because let variables are hoisted to the top of their block scope, but they are not initialized until the actual declaration statement.
Hoisting with const
Now, let's delve into hoisting with const. The behavior of const is somewhat similar to let concerning hoisting.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hoisting with const</title>
</head>
<body>
<script>
console.log(age); // Error: Cannot access 'age' before initialization
const age = 30;
console.log(age); // Output: 30
</script>
</body>
</html>
As with let, trying to access a const variable before its declaration throws a ReferenceError. This is because, like let, const variables are hoisted to the top of their block scope but remain uninitialized until the actual declaration statement.
Hoisting and Temporal Dead Zone (TDZ)
One crucial aspect to understand with let and const is the Temporal Dead Zone (TDZ). The TDZ is the period between entering a scope and the actual initialization of a let or const variable.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Temporal Dead Zone (TDZ)</title>
</head>
<body>
<script>
console.log(age); // Error: Cannot access 'age' before initialization
let age = 30; // TDZ starts
console.log(age); // Output: 30
</script>
</body>
</html>
In this example, trying to access age before its declaration initializes the TDZ, leading to a ReferenceError. Once age is declared, it exits the TDZ, and accessing it works fine.
Hoisting in Functions
Hoisting also applies to function declarations:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hoisting with Functions</title>
</head>
<body>
<script>
sayHello(); // Output: Hello
function sayHello() {
console.log('Hello');
}
</script>
</body>
</html>
In this case, the sayHello function is hoisted to the top, so calling it before its actual declaration works without errors.
Practice Excercise Practice now