Learn JS. Hoisting (2). Temporal Dead Zone

In my previous post Learn JS. Hoisting (1), I've explained how Lexical Environment is responsible for what most people call hoisting. Hoisting is not a term from the specification but is a label for how Lexical Environment works in JavaScript. The same will be true for the Temporal Dead Zone.

Let's start with an example.

console.log(bar); // undefined
console.log(foo); // throws ReferenceError
var bar = 1;
let foo = 2;

Let's figure it out step by step, looking at how Lexical Environment looks like before execution.

LexicalEnvironment = {
bar: undefined
foo: < uninitialized > // throw ReferenceError if anyone tries to access it

var, let and const declarations are hoisted. The only difference is what happens when you try to access the variable before the declaration.

Let's take a look at specification:

The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable's LexicalBinding is evaluated.
from: http://ecma-international.org/ecma-262/#sec-let-and-const-declarations

Let me show you an example with LexicalBinding:

// LexicalEnvironment = { foo: < uninitialized > - throw Reference Error }

let foo = 2; // LexicalBinding!

// LexicalEnvironment = { foo: 2 }

Just for completeness the same is true for consts:

// LexicalEnvironment = { FOO: < uninitialized > - throw Reference Error }

const FOO = 2; // LexicalBinding!

// LexicalEnvironment = { FOO: 2 }

Temporal Dead Zone #

Every line of code when the value in Lexical Environment is equal to <uninitialized> is commonly called Temporal Dead Zone as you can't use identifiers (names) of your const or let variables before their declarations.

// LexicalEnvironment = { FOO: < uninitialized > - throw Reference Error }
// Temporal Dead Zone: Start
const FOO = 2; // LexicalBinding!
// Temporal Dead Zone: END

// LexicalEnvironment = { FOO: 2 }

What if there is no initial value? #

Let's say that you declare your let variable but you calculate it's value later. What will happen to Temporal Dead Zone? Will there be LexicalBinding?

// LexicalEnvironment = { bar: < uninitialized > - throw Reference Error }
// Temporal Dead Zone: Start
let bar; // LexicalBinding!
// Temporal Dead Zone: END
// LexicalEnvironment = { bar: undefined }

console.log(bar); // undefined

bar = "some value"
// LexicalEnvironment = { bar: "some value" }

Both let and const get undefined as a value until you assign one. Of course, after the LexicalBinding.

Share on Hacker News
Share on LinkedIn

← Home

Want to learn more?

Sign up to get a digest of my articles and interesting links via email every month.

* indicates required

Please select all the ways you would like to hear from Krzysztof Kula:

You can unsubscribe at any time by clicking the link in the footer of my emails.

I use Mailchimp as a marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.