The Temporal Dead Zone

corinamurg

Corina: Web for Everyone

Posted on November 2, 2023

The Temporal Dead Zone

JavaScript's Restricted Realm for LET and CONST

The Temporal Dead Zone sounds like a sci-fi movie, doesn't it? But in the JavaScript universe, it's the space where a variable is off-limits, even though you might think it should be available. This behavior occurs with variables declared using let and const.


In this post we will answer the following questions:

  1. What is the Temporal Dead Zone?

  2. Where or when do we encounter it?

  3. Why do we have it?

Before we dive any deeper though, let's review hoisting.

Hoisting: What is it again?!

In The Curious Case of JavaScript Hoisting we talked about how both variable and function declarations are moved - or hoisted - to the top of their containing scope during the compilation phase.

However, not all hoisting is created equal. While function declarations are hoisted with their definitions, allowing us to call them even before their code appears, variables show more nuances:

  • Variables declared with var are hoisted, but their initialization stays where it is. This means they'll exist (with an undefined value) from the beginning of their scope, but they won't get their assigned value until the code execution reaches the point of initialization.

  • In contrast, variables declared with let and const are also hoisted but they enter a 'Temporal Dead Zone'. They remain inaccessible until the point of initialization, and any attempt to access them prematurely will throw an error.

Let's look at an example!

A Variable Declaration with var

console.log(myCat) -> undefined

var myCat = "Petunia"
Enter fullscreen mode Exit fullscreen mode

In the code above, the var myCat declaration is hoisted to the top of the scope, but its initialization with the value Petunia is not. This is why it returns undefined when we try to log it before actually defining it.

Now you might ask: what about let and const? Do they also get hoisted? Indeed, they do! JavaScript hoists all declarations, it's very uplifting in that manner. ๐Ÿ˜Š

Yet, while hoisting applies to all three, let and const get special treatment - they get sent to the Temporal Dead Zone! ๐Ÿ’€

The Temporal Dead Zone ๐Ÿšซ

The Temporal Dead Zone (TDZ) is JavaScript's no-access zone. When a let or const variable is hoisted, it enters the TDZ. From the start of the block until the line where the variable is declared, it's in the TDZ. Attempt to access it too soon, and JavaScript throws a ReferenceError.

console.log(myVar)   // Output: undefined
var myVar = 'red'    // myVar is now delcared
console.log(myVar)   // Output: 'red'

console.log(myLet)   // ReferenceError: myLet is not defined
let myLet = 'orange' // myLet is now declared
console.log(myLet)   // Output" 'orange'
Enter fullscreen mode Exit fullscreen mode

Notice how myVar floats up like a helium balloon and is undefined before the line where itโ€™s actually tied down. This behavior is because of how var declarations are hoisted. On the other hand, myLet does get hoisted but lounges in the TDZ until the let myLet = "orange" line runs.

Here's an example using const inside a block scope:

{  // start of the block scope

 console.log(cat)      // ReferenceError: cat is not defined
 const cat = "furry"   //  Ah, now cat is finally declared!
 console.log(cat)      // "furry"

}  // End of the block scope
Enter fullscreen mode Exit fullscreen mode

In this example, the scope of cat is the entire block (the code within the { }). The TDZ for cat is the stretch of this block until right before the const cat = "furry" line. Once we pass that line of code, the cat is out of the TDZ ... and out of the bag, ready to be used (and cuddled).

Phew, I am finally in the clear! ๐Ÿ˜ธ

Finally: Why Does the TDZ Exist?

Understanding the TDZ is one thing, but you might wonder why such a concept exists in the first place.

The idea behind the TDZ is to help catch bugs in your code. Deciding between var, let, and const for variable declaration? The strict behavior of let and const in TDZ suggests that they are generally better choices for writing robust, debuggable code.

When you declare a variable using var, it gets hoisted and initialized with undefined. Using the variable before it's defined could lead to unexpected behavior, but you will not necessarily see an immediate error. Your code will not explicitly fail; it just operates unexpectedly.

Let's remember an example from a previous post:

var result = 2 * myVar // Output: NaN

var myVar = 7;
Enter fullscreen mode Exit fullscreen mode

In this scenario, result will be NaN because myVar is undefined at the time of the multiplication, and any arithmetic operation involving undefined results in NaN. These types of bugs are subtle and can be tricky to debug as they donโ€™t throw an error and might not become apparent until much later in the programโ€™s execution.

On the other hand, let and const put the variable in the Temporal Dead Zone until it's declared and initialized. If you try to access the variable while it's in the TDZ, JavaScript throws a ReferenceError and the code execution stops; you learn about the potential problem immediately.

Takeaway

Oh, the intricacies of scope, hoisting, and the Temporal Dead Zone! Only in JavaScript, right? It pays to remember them in order to produce bug-resistant code. So, the next time you declare a variable, remember these quirks and choose wisely!

Happy Halloween month! ๐ŸŽƒ ๐Ÿ˜ธ

Resources

JavaScript: The Definitive Guide
7th Edition, by David Flanagan
O'Reilly Media, 2020

Blog post: The Curious Case of JavaScript Hoisting

Blog post: Demystifying Function Declarations Within Conditional Blocks

Blog post originally published October 2, 2023 on corinamurg.dev.

๐Ÿ’– ๐Ÿ’ช ๐Ÿ™… ๐Ÿšฉ
corinamurg
Corina: Web for Everyone

Posted on November 2, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

The Temporal Dead Zone
javascript The Temporal Dead Zone

November 2, 2023

ยฉ TheLazy.dev

About