Hoisting with let & const vs var in JS and TDZ?
Navigating the Hoisting Maze: Unravelling JavaScript's Secrets
Hello, peeps!
Today, let's embark on an exploration into the depths of JavaScript's hoisting and examine the complicated world of the Temporal Dead Zone (TDZ).
Get ready for some thought-provoking examples that will clarify these ideas.
Hoisting: A Deeper Dive
To truly grasp hoisting, let's examine a more complex scenario involving functions and block-level declarations.
console.log(foo); // undefined
console.log(bar); // ReferenceError: Cannot access 'bar' before initialization
var foo = 'I am hoisted!';
let bar = 'I am in the TDZ!';
function hoistingExample() {
console.log(foo); // I am hoisted!
console.log(bar); // ReferenceError: Cannot access 'bar' before initialization
var foo = 'Function scope hoisting!';
let bar = 'Function scope TDZ!';
}
hoistingExample();
In this example, var foo
is hoisted to the top of the function scope, but its value is still undefined
until the actual declaration. On the other hand, let bar
is hoisted to the top of the block (function in this case), but accessing it before declaration results in a TDZ error.
The Temporal Dead Zone Chronicles
Let's delve even deeper into the Temporal Dead Zone with a nested example.
function nestedExample() {
console.log(outer); // undefined
console.log(inner); // ReferenceError: inner is not defined
var outer = 'I am in the TDZ!';
if (true) {
let inner = 'I am hoisted, but still in the TDZ!';
console.log(inner); // I am hoisted, but still in the TDZ!
console.log(outer); // I am in the TDZ!
outer = 'I escaped the TDZ!';
}
console.log(outer); // I escaped the TDZ!
console.log(inner); // ReferenceError: 'inner' is not defined
}
nestedExample();
In this scenario,
console.log(outer); // undefined
:var outer
is hoisted, but undefined until the declaration.console.log(inner); // ReferenceError: inner is not defined
:let inner
is in the TDZ, causing a ReferenceError.console.log(inner); // I am hoisted, but still in the TDZ!
: Inside theif
block,inner
is accessible.console.log(outer); // I am in the TDZ!
:var outer
is accessible and logged within the block.console.log(outer); // I escaped the TDZ!
: Updated value ofouter
logged outside the block.console.log(inner); // ReferenceError: 'inner' is not defined
: Attempting to accessinner
outside the block results in a ReferenceError.
Temporal Dead Zone (TDZ) โ the time between hoisting and variable initialization. Any line of code before the declaration and initialization of a let
variable is considered the TDZ for that variable.
let a = 10;
var b = 15;
console.log(window.b); // 15
console.log(window.a); // undefined
In this example, until the line let a = 10
, a
is in the TDZ and cannot be accessed. This applies not only to the global context (window
or this
) but also to any other scope.
Stricter than Strict: const
Now, let's talk about const
. It's the strictest of them all. Once a value is assigned to a const
variable, it cannot be reassigned. This adds an extra layer of immutability to your code.
Best Practices
To navigate through these intricacies, here are some best practices:
Prefer
const
: Useconst
whenever possible. It enhances code readability and ensures immutability.Fallback to
let
: If reassignment is necessary, uselet
. Avoidvar
as it may lead to unexpected behavior.Declare and Initialize at the Top: To minimize the TDZ window and prevent errors, declare and initialize variables with
let
at the top of their scope.
These techniques will help you develop more reliable, cleaner JavaScript code.
Thank you! ๐