Variables
Three ways to declare variables in JavaScript - var, let, and const - each with different scoping and hoisting rules.
JavaScript has three variable declaration keywords: var, let, and const. They differ in scope, hoisting, and reassignability. Modern code uses const and let exclusively.
const declares a block-scoped binding that cannot be reassigned. It is the right choice for most declarations - it signals that the value won't change, which makes code easier to reason about.
const name = "Ada";
name = "Grace"; // TypeError: Assignment to constant variable.let is block-scoped and allows reassignment. Use it only when a variable genuinely needs to change - a loop counter, an accumulator, a flag that flips once.
let count = 0;
count = count + 1;
console.log(count); // 1
for (let i = 0; i < 3; i++) {
console.log(i); // 0, 1, 2
}
// i is not accessible herevar is function-scoped and hoisted to the top of its function. A var declared inside an if block leaks into the surrounding function - a frequent source of bugs in older code.
function demo() {
if (true) {
var x = 1; // hoisted to function scope
}
console.log(x); // 1 - leaks out of the if block
let y = 2;
// y stays block-scoped - won't leak
}In production
The modern convention is const by default, let only when reassignment is genuinely required, and var never. ESLint's prefer-const and no-var rules enforce this automatically. Teams that skip these rules accumulate subtle bugs in async code: a var in a loop body captured by a closure resolves to the final loop value, not the value at the iteration where the closure was created - a class of bug that let eliminates entirely.
Enjoyed this? Get more essays on software craft delivered to your inbox.
Subscribe free