JavaScript Variable Declarations: let vs var Deep Dive
Block-Level Scoping with let
Before ECMAScript 6, JavaScript lacked block-level scope. Variables declared with var inside blocks remained accessible outside them:
{
var score = 95;
}
console.log(score); // 95
The let keyword introduced true block scoping:
{
let score = 95;
}
console.log(score); // ReferenceError: score is not defined
Hoisting Behavior and Temporal Dead Zone
Variables declared with var are hoisted and initialized with undefined:
function showValue() {
console.log(temp); // undefined
var temp = 25;
console.log(temp); // 25
}
let declaration are hoisted but remain in a "temporal dead zone" until execusion reaches the declaration:
console.log(message); // ReferenceError: Cannot access 'message' before initialization
let message = "Hello";
Accessing a let variable before its declaration triggers a runtime error.
Loop Constructs and Asynchronous Behaviorr
A common pitfall with var in loops creates unexpected closure behavior:
for (var idx = 0; idx < 3; idx++) {
setTimeout(() => {
console.log(idx); // 3, 3, 3
}, 0);
}
Each timeout references the same idx variable. Using let creates a new binding for each iteration:
for (let idx = 0; idx < 3; idx++) {
setTimeout(() => {
console.log(idx); // 0, 1, 2
}, 0);
}
Redeclaration Restrictions
Unlike var, let prohibits duplicate declarations in the same scope:
let configValue = true;
let configValue = false; // SyntaxError: Identifier 'configValue' has already been declared
This prevents accidental variable overwriting and improves code reliability.