Temporal Dead Zone and Hoisting in Javascript - A Quick Guide with example
Commonly asked question in a Javascript Interview
Hello there! If you're currently learning JavaScript or working as a web developer, chances are you've encountered the concepts of Temporal Dead Zone (TDZ) and Hoisting. These topics are fundamental to understanding how JavaScript variables are declared and assigned values. You may have even been asked about them during a technical interview.
Don't worry, I'll take you to the grand line of Javascript.
Before we explore these terms, it's helpful to understand the basics of how JavaScript works.
How does Javascript work?
When the JavaScript engine (such as a web browser) begins to execute a JavaScript file, it creates a global execution context. This context is like a container that holds all the code and data related to the current execution of the script.
You may be wondering what exactly an execution context is. Simply put, it's an environment consisting of two key elements -
Memory (Variable Environment) - This is where every variable or function used in the code is stored as a key-value pair. The memory is organized in a way that allows the JavaScript engine to easily retrieve and use these variables and functions as needed.
Thread of Execution - This is a single thread where the JavaScript code is executed. The thread of execution reads and executes the code line by line, following the rules and syntax of the JavaScript language.
Execution of Javascript
The execution of JavaScript occurs in two distinct phases:
Memory Allocation - During this phase, the browser processes all the declarations in the code, giving them higher specificity. This does not necessarily mean that all the declarations are physically moved anywhere, but rather that the browser is aware of their existence.
Code Execution - Once all the declarations have been processed and stored in memory, the browser begins to execute the program's code. During this phase, the browser reads the code line by line and performs the necessary operations based on the language's syntax and rules.
If all of this information seems overwhelming, don't worry! Let me explain with an example.
Consider the following program:
console.log(a); // prints undefined
console.log(b); // gives reference error
console.log(c); // gives reference error
console.log(sum); //prints function body
var a = 10; // set to 10
let b = 20; // set to 20
const c = 30; // set to 30
function sum(a,b) {
return a + b;
}
Memory Phase
During the first phase, all variables (a, b, and c) as well as the function "sum" are stored in memory.
The resulting execution context would look something like this:
Key | Value | Remarks |
a | undefined | Allocated memory in global space |
b | <no value assigned> | allocated memory in script space but without any value |
c | <no value assigned> | allocated memory in script space but without any value |
sum | f sum(a,b) { return a + b; } | The body of the function is stored inside the memory |
Execution Phase
During the second phase, the code execution begins with Line 1.
console.log(a) - When Line 1 is executed, it will print
undefined
, as this is the initial value stored in memory for the variablea
.console.log(b) or console.log(c) - Since the variables
b
andc
have not yet been initialized, attempting to reference them will result in a reference error. The error message typically looks something like this:Uncaught ReferenceError: Cannot access 'b' before initialization
Uncaught ReferenceError: Cannot access 'c' before initialization
console.log(sum) - When executed, this statement will print the body of the "sum" function as it is stored in memory.
var a = 10 - The variable
a
is assigned the value of 10.let b = 20 - The variable
b
is assigned the value of 20.const c = 30 - The variable
c
is assigned the value of 30.It's important to note that a function declaration does not execute anything on its own, as it is not invoked until called.
Hoisting
As you can see, variables declared with the var
keyword can be accessed before they are even declared and initialized. This behaviour is known as hoisting
in JavaScript.
From MDN,
JavaScript Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables or classes to the top of their scope, before the execution of the code.
Temporal Dead Zone (TDZ)
Similarly, variables declared with the let
and const
keywords are also stored in memory before initialization, but attempting to access them before they are initialized will result in a Temporal Dead Zone (TDZ) error. This means that these variables cannot be accessed before they are initialized, even though they are present in memory.
From MDN,
A
let
orconst
variable is said to be in a "temporal dead zone" (TDZ) from the start of the block until code execution reaches the line where the variable is declared and initialized.
Before Lines 5 and 6 are executed, variables b
and c
are in the TDZ.
The resulting execution context would look like this before the execution ends.
Key | Value | Remarks |
a | 10 | Set to 10 after line 4 executes. |
b | 20 | Set to 20 after line 5 executes. |
c | 30 | Set to 30 after line 6 executes. |
sum | f sum(a,b) { return a + b; } |
After initialization, if you log the values of the variables to the console, they will display their assigned values.
console.log(a); // prints undefined
console.log(b); // gives reference error
console.log(c); // gives reference error
console.log(sum); //prints function body
var a = 10; // set to 10
let b = 20; // set to 20
const c = 30; // set to 30
console.log(a); // prints 10
console.log(b); // prints 20
console.log(c); // prints 30
function sum(a,b) {
return a + b;
}
Bonus Question
var sumFn = function(a, b) {
return a + b;
} // This is called Function Expression.
function sum(a,b) {
return a + b;
} // This is called Function Statement/Function Declaration.
// Note - Function Statement and Function Declaration are same.
Given this code, which type of function, function expression or function declaration, is hoisted in JavaScript?
Answer
In JavaScript, only function declarations are hoisted to the top of the current scope, meaning they can be accessed and called before they are declared in the code.
Function expressions, on the other hand, are not hoisted in the same way, and only the variable declaration is hoisted. As a result, if you try to access a function expression before it is declared, the variable will be set to undefined
. This behaviour depends on the type of variable declaration used (var
or let
).
It's important to note that only function declarations will be able to print the entire function body when accessed before the declaration.
If you guessed correctly, here's a ๐ช for you. But only if you guessed it correctly! ๐
Hope that this makes you feel a bit more comfortable with the concept of Hoisting and Temporal Dead Zone in JavaScript. If you have any questions or feedback, feel free to reach out to me on Twitter. I'd be happy to help.
Also, if you're interested in learning more about commonly asked HTML, CSS, and JavaScript questions, be sure to follow me for regular blog updates.
If you found this information helpful, kindly consider giving a like โค๏ธ as appreciation.