Div’s Blog

August 16, 20192 min read

Temporal Dead Zone

When a block scoped variable (let or const) is declared, and before it’s initialized, it remains in a state called the Temporal Dead Zone (TDZ). While in this state, the variable can’t be accessed and will throw a ReferenceError.

console.log(a); // undefined
console.log(b); // ReferenceError
var a = 13;
let b = 42;

Same is true for const. The typeof operator also throws a ReferenceError when a variable is in TDZ.

console.log(typeof undeclaredVariable); // undefined
console.log(typeof c); // ReferenceError
let c = 3;

Hoisting

From the above examples, it appears as if the block scoped variables, unlike var, are not hoisted. However, that is not true. let and const declarations are also hoisted to the lexical scope. They remain in the TDZ till they’re initialized.

let blockVariable = 7;

{
	// blockVariable declaration will be hoisted to this lexical scope
	console.log(blockVariable); // ReferenceError
	let blockVariable = 8;
}

From this example, we might expect the console.log to print 7. However, the declaration of blockVariable in the inner scope is hoisted to the lexical scope which puts it in a state of TDZ when the console.log is executed.

Need for TDZ

Block scoped variables let and const work differently from var. Any var variables are hoisted and initialized with a value of undefined. For let and const, initialization with undefined doesn’t happen with hoisting.

TDZ primarily exist to satisfy the constraints of const. const signifies that the variable can’t be reassigned to a different value. If const worked in the same way as var, it would have implied the variable to have two values, an undefined when hoisted and later the value with which it would have been initialized with. Consider the following:

// if constantVariable would have assigned undefined when hoisted
// like var, it would have to be reassigned to 99 later
// which would be against the constraints of const

console.log(constantVariable); // ReferenceError
const constantVariable = 99;

let follows the same semantics for TDZ as const to make this behavior similar. This also helps in avoiding possible bugs which might have arrived from accessing variables before they were initialized.

External links


Divyanshu Maithani

Personal blog of Divyanshu Maithani. I’m a JavaScript engineer working with React, React Native, GraphQL and Node. I also create programming videos with my friend. In my spare time I play music and DoTA.

You may follow me on twitter or join my newsletter for latest updates.