Hoisting
TL;DR
- Variable and function declarations are "hoisted" to the top of their respective scope.
- Hoisting doesn't actually move the code, but is related to the compilation process of the JavaScript engine.
- The compilation process is divided into a creation phase and an execution phase. During the creation phase, memory locations are created for variables, while during the execution phase, values are assigned.
What is hoisting
In JavaScript, hoisting refers to the behavior of variables and function declarations being lifted to the top of their scope.
Variable declarations using var
, let
, or const
are all hoisted.
However, the term "hoisting" can be misleading, as it implies that the code is physically moved, when in reality it's a part of the compilation process.
// actual code
console.log(a);
var a = 1;
// interpreted by the JavaScript engine as
var a;
console.log(a);
a = 1;
Compilation Process
In JavaScript, the compilation process can be divided into two phases:
- Creation:The JavaScript engine creates memory space for variables and function declarations. For variables, the default value is
undefined
, while for function declarations, the default value is the function itself. - Execution:The program is executed line by line, and values are assigned based on the executed code.
Taking the following code as an example:
console.log(a); // undefined
var a = 1;
logName(); // jordan
function logName() {
console.log('jordan');
}
The JavaScript compilation process is as follows:
- Creation
- A memory location named
a
is created, with a default value ofundefined
. - A memory location named
logName
is created, with a default value of thelogName
function declaration itself.
- Execution:
console.log(a)
is executed, outputtingundefined
, because the default value of a isundefined
.var a = 1
is executed, assigning an initial value of 1 to the variablea
.logName()
is executed, outputting "jordan", because the default value oflogName
is the logName function declaration itself.
Temporal Dead Zone
In JavaScript, variables are hoisted regardless of whether they are declared with var
, let
, or const
.
However, why does the following code throw an error 🤔
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 1;
This is due to the concept of Temporal Dead Zone (TDZ) in JavaScript.
The Temporal Dead Zone is the area of a block where a variable is inaccessible until the moment the computer completely initializes it with a value.
During the TDZ, any attempt to access the variable will result in a ReferenceError
.
The TDZ can prevent variables from being accidentally used before they are declared, thereby reducing code errors and increasing code reliability.
console.log('Jordan');
console.log('John');
console.log(a);
// the above is the TDZ for variable a, which cannot be accessed
const a = 1; // The TDZ of let and const ends when the variable is initialized
The TDZ of let
and const
ends when the variable is initialized.
The TDZ of var
ends at the beginning of the execution phase.
In this example code, it will not throw a ReferenceError
because the variable a
is declared by var
.
// The TDZ of `var` ends at the beginning of the execution phase
console.log('Jordan');
console.log('John');
console.log(a);
var a = 1;
undefined
vs. not defined
undefined
:A primitive value that is automatically assigned to variables during that have been declared but have not been initialized with a value.- not defined:A variable that has not been declared in the current scope or in any parent scope. This will result in a
ReferenceError
when trying to access it.
var a;
console.log(a); // undefined
console.log(b); // ReferenceError: a is not defined
FAQ
Determine the result
let a = 1;
{
console.log(a);
let a = 2;
}Answer:
The result of the code will be a
ReferenceError
because of the concept of temporal dead zone (TDZ) in JavaScript.In the creation phase, memory space is created for the global variable
a
and a local variablea
inside the block.During the execution phase, when
console.log(a)
is executed inside the block, the local variablea
is in the TDZ as it has not been initialized yet. Therefore, trying to accessa
at this point will result in aReferenceError
.Determine the result
var logName = function () {
console.log('jordan');
};
function logName() {
console.log('john');
}
logName();Answer:
Creation:
- When both variable and function declaration use the same name, the function declaration takes priority over the variable declaration.
- Create memory space for the function
logName
with a default value oflogName
itself.
Execution:
The function
logName
is reassigned tofunction () { console.log('jordan'); }
.Execute
logName()
and print out 'jordan'.
Reference: