Temporal Dead Zone (TDZ)

What is Temporal Dead Zone?

The Temporal Dead Zone (TDZ) is the period between entering scope and being declared where variables cannot be accessed. This applies to let and const declarations.

Try Temporal Dead Zone

Code Editor
Console Output
Click "Run" to execute your code...

Example 1: Basic TDZ

// TDZ Example with let
{
  // TDZ starts here for 'myVar'
  // console.log(myVar); // ReferenceError: Cannot access 'myVar' before initialization
  
  let myVar = 10; // TDZ ends here
  console.log(myVar); // 10
}

// TDZ Example with const
{
  // TDZ starts here for 'myConst'
  // console.log(myConst); // ReferenceError
  
  const myConst = 20; // TDZ ends here
  console.log(myConst); // 20
}

// var does NOT have TDZ
{
  console.log(myVarVariable); // undefined (not an error)
  var myVarVariable = 30;
  console.log(myVarVariable); // 30
}

Example 2: TDZ in Function Parameters

// TDZ in default parameters
function test(a = b, b = 2) {
  // Error: 'b' is in TDZ when 'a' tries to use it
  return [a, b];
}
// test(); // ReferenceError: Cannot access 'b' before initialization

// Correct order
function testCorrect(a = 2, b = a) {
  return [a, b];
}
console.log(testCorrect()); // [2, 2]
console.log(testCorrect(5)); // [5, 5]

// Another example
function create(x = y, y = 2) {
  return [x, y];
}
// create(); // ReferenceError: Cannot access 'y' before initialization

function createCorrect(y = 2, x = y) {
  return [x, y];
}
console.log(createCorrect()); // [2, 2]

Example 3: TDZ and typeof

// typeof with undeclared variable (no error)
console.log(typeof undeclaredVariable); // "undefined"

// typeof in TDZ (throws error!)
{
  // console.log(typeof myLet); // ReferenceError
  let myLet = 10;
}

// This is a breaking change from var behavior
console.log(typeof myVar); // "undefined"
var myVar = 20;

// Practical implication
function checkVariable() {
  // console.log(typeof x); // ReferenceError: Cannot access 'x' before initialization
  let x = 5;
  return x;
}

Example 4: TDZ in Loops

// TDZ in for loop
for (let i = 0; i < 3; i++) {
  // Each iteration creates a new 'i' in its own scope
  setTimeout(() => console.log(i), 100);
}
// Output: 0, 1, 2

// TDZ applies to each iteration
for (let i = 0; i < 3; i++) {
  // let j = i + j; // ReferenceError: 'j' in TDZ
  let j = i + 1;
  console.log(j); // 1, 2, 3
}

// Block scope creates TDZ
{
  let items = [1, 2, 3];
  for (let i = 0; i < items.length; i++) {
    // let value = items[i] + value; // ReferenceError
    let value = items[i] + 10;
    console.log(value); // 11, 12, 13
  }
}

Example 5: TDZ Best Practices

// ❌ Bad: Using before declaration
function badExample() {
  console.log(name); // Would cause TDZ error
  let name = 'John';
}

// ✅ Good: Declare at the top
function goodExample() {
  let name = 'John';
  console.log(name); // Works fine
}

// ❌ Bad: Complex initialization order
function calculatePrice() {
  const total = price * quantity; // ReferenceError
  const price = 10;
  const quantity = 5;
  return total;
}

// ✅ Good: Declare in correct order
function calculatePriceCorrect() {
  const price = 10;
  const quantity = 5;
  const total = price * quantity;
  return total;
}
console.log(calculatePriceCorrect()); // 50

// ✅ Best: Group related declarations
function processData() {
  // Declare all variables at the top
  const input = getData();
  const processed = transform(input);
  const result = validate(processed);
  
  return result;
  
  function getData() { return [1, 2, 3]; }
  function transform(data) { return data.map(x => x * 2); }
  function validate(data) { return data.filter(x => x > 0); }
}

console.log(processData()); // [2, 4, 6]

Key Points

  • TDZ exists for let and const, but not for var
  • Variables in TDZ cannot be accessed, even with typeof
  • TDZ starts at the beginning of the scope and ends at the declaration
  • Accessing a variable in TDZ throws ReferenceError
  • Best practice: Declare variables at the top of their scope
  • TDZ helps catch programming errors early