What is Hoisting in JavaScript?
I will try to write, in my own words, a brief explanation of what hoisting is in JavaScript, the conditions under which it happens, and common mistakes we make.
Hoisting
Hoisting is a term that emerged in the JavaScript world starting from ECMAScript 2015 and, in short, it allows functions, variables, and classes to be called before they are defined, depending on some factors that we will discuss below.
Hoisting is JavaScript's ability to store all variable and/or function declarations in memory during compilation so they can be used when called. This does not mean that the declarations are physically moved to the top of the context in which they are found; they are simply allocated in memory before the code execution.
Variables
Only declarations are hoisted, not initializations. This means that you cannot assign a value to the variable after its use. In such a scenario, the variable will have a value of undefined
.
It is also important to note that only variables created with var
are hoisted, while const
and let
are not. If you try to use a constant (const) before its declaration, the application will throw a reference error.
Examples
value = 2024
console.log('Value', value)
// Will show "2024"
var value
console.log('Another Value', anotherValue)
// Will show "undefined"
var anotherValue = 2024
newLet = 2024
console.log('New Let', newLet)
// Will throw an error like this:
// ReferenceError: Cannot access 'newLet' before initialization
let newLet
console.log('Another Let', anotherLet)
// Will throw an error like this:
// ReferenceError: Cannot access 'anotherLet' before initialization
let anotherLet = 2024
console.log('Another Const', anotherConst)
// Will throw an error like this:
// ReferenceError: Cannot access 'anotherConst' before initialization
const anotherConst = 2024
Functions
Function declarations in JavaScript are hoisted, but function expressions are not.
Examples
sayHello("John");
function sayHello(name) {
console.log("Hello " + name);
}
// Will show "Hello John"
sayGoodbye("John");
const sayGoodbye = (name) => {
console.log("Goodbye " + name);
};
// Will throw an error like this:
// ReferenceError: Cannot access 'sayGoodbye' before initialization
saySomething("John");
const saySomething = function (name) {
console.log("Something, " + name);
};
// Will throw an error like this:
// ReferenceError: Cannot access 'saySomething' before initialization
Temporal Dead Zone (TDZ)
Variables declared with const
, let
, or class
are considered within the Temporal Dead Zone TDZ from the start of the block until their declaration. Therefore, when we try to use one of these variables before its declaration, JavaScript returns a ReferenceError
. But more details about this will be covered in a future post.