Hoisting and the Temporal Dead Zone (TDZ)

Hoisting and the Temporal Dead Zone (TDZ)

Prerequisites

  • Understand what an execution context is and its phases.
  • Understand how to determine the scope of a variable in JavaScript.

Hoisting

Hoisting is the process by which JavaScript allocates memory for variable and function declarations.

When Does Hoisting Occur

Hoisting occurs before code execution during the creation phase of an execution context. Recall that the JavaScript engine allocates a variable environment to store local variables during the creation phase of an execution context. When we access a variable or function in our program, we access a property on the variable environment.

The JavaScript engine, during hoisting, scans the code for variable and function declarations, and with each declaration, the JavaScript engine adds a property to the variable environment. The initial value associated with each property depends on how the variable or function was declared.

Hoisting Rules

TypeInitial ValueWhat it means
Function DeclarationActual FunctionYou can access and call a function before its declaration
varundefinedYou can access a variable declared with var before its declaration, but it will have an undefined value. Because the variable exists in the scope, it will not result in an error.
let and constuninitializedYou can't access a variable declared with let and const before its declaration. Variables declared with let and const don't exist in the scope until you declare them. Thus you will get an error when you try to access the variable.
Function expressions and arrowsIt depends on whether the function expression or arrows uses var, let, or constIt will follow the rules of the keyword used to define the function

Visualizing Hoisting

A visualization of hoisting

Stop and think

What will the call to the function greet() in the code below output?

function greet() {
  console.log('Hello');
}

greet();

function greet() {
  console.log('Jambo');
}
Answer

Answer: Jambo

Remember, the JavaScript engine hoists function declarations before code execution, with the initial value being the function. We have a function called greet declared twice; therefore, the JavaScript engine will hoist the greet function declared last.

Recall also that when we access a variable, we are accessing the properties on the variable environment. The variable environment doesn't change for function declarations when code execution begins. Therefore, when we call greet anywhere in our program, the value hoisted will be used, and in our case, it is the greet function declared last.

Temporal Dead Zone (TDZ)

Recall from the hoisting rules that variables declared with let and const don't exist until we declare them.

TDZ is a fancy term for the region within a scope for which a variable is declared but can't be accessed. The TDZ starts at the beginning of the scope till when the variable is defined.

Illustration of TDZ

In the code example above, the TDZ of the variable square is the region highlighted in purple. Trying to access the variable square in that region will result in an error.

Test Your Understanding

1. What is the output?
if (!s) {
  console.log(t);
  var t = 8;
  console.log(t);
}

var s = 10;

if (s === 10) {
  console.log(t);
}
Answer

undefined

8

8

The variable s is hoisted with the initial value being undefined. The first if block, therefore, accesses a variable before its declaration and shows the dangers of declaring variables with the var keyword. With ES6, stick to declaring variables with let and const.

2. What is the output?
var favoriteCar = 'Lamborghini';

function foo() {
  console.log(favoriteCar);
  var favoriteCar = 'Porsche';
  console.log(favoriteCar);
}

foo();

console.log(favoriteCar);
Answer

undefined

Porsche

Lamborghini

Variables declared with var have function scope. When we call the function foo, we create a new execution context, and thus the variable favoriteCar gets hoisted in this new execution context's variable environment.

3. What is the output?
function greet() {
  function a() {
    console.log('Ola');
  }
  return a();
  function a() {
    console.log('Hello');
  }
}

greet();
Answer

Hello

Remember, function declarations get hoisted before code execution, with the actual function as the initial value. While statements after the return keyword are unreachable during execution, the function was already hoisted.

4. What is the output?
const radius = 15;

function computeCircumference(radius) {
  return 2 * PI * radius;
}

const PI = 3.14;
const square = computeCircumference(radius);
console.log(square);
Answer

94.2

5. What is the output?
var y = 7;

if (true) {
  var y = 10;
  console.log(y);
}

console.log(y);
Answer

10

10

Variables declared with var can be redclared.