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
ais created, with a default value ofundefined. - A memory location named
logNameis created, with a default value of thelogNamefunction declaration itself.
- Execution:
console.log(a)is executed, outputtingundefined, because the default value of a isundefined.var a = 1is executed, assigning an initial value of 1 to the variablea.logName()is executed, outputting "jordan", because the default value oflogNameis 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
ReferenceErrorwhen 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
ReferenceErrorbecause of the concept of temporal dead zone (TDZ) in JavaScript.In the creation phase, memory space is created for the global variable
aand a local variableainside the block.During the execution phase, when
console.log(a)is executed inside the block, the local variableais in the TDZ as it has not been initialized yet. Therefore, trying to accessaat 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
logNamewith a default value oflogNameitself.
Execution:
The function
logNameis reassigned tofunction () { console.log('jordan'); }.Execute
logName()and print out 'jordan'.
Reference: