var vs let vs const
The real differences between JavaScript's three variable declarations — scope, hoisting, and reassignment.
2 min read
JavaScript has three ways to declare a variable, and they behave differently enough that mixing them up causes real bugs. let and const (both added in ES6) are what modern code should use; var is the original, older keyword you'll still encounter in legacy code.
Scope: function vs block
var is scoped to the nearest function (or the global scope if there isn't one) — it ignores blocks like if and for entirely:
if (true) {
var x = 10;
}
console.log(x); // 10 -- leaked out of the if blocklet and const are scoped to the nearest block ({ }), which matches what most other languages do and what programmers generally expect:
if (true) {
let y = 10;
}
console.log(y); // ReferenceError: y is not definedReassignment: let vs const
let can be reassigned; const cannot:
let count = 1;
count = 2; // fine
const max = 100;
max = 200; // TypeError: Assignment to constant variable.const only prevents reassigning the variable itself — it doesn't make objects or arrays immutable. Their contents can still change:
const user = { name: "Ada" };
user.name = "Grace"; // fine -- mutating a property, not reassigning `user`
user = {}; // TypeError -- this is a reassignmentHoisting and the temporal dead zone
All three declarations are hoisted — JavaScript registers the variable name at the top of its scope before running any code — but they behave differently when accessed before their declaration line. var is hoisted and initialized to undefined, so reading it early gives undefined instead of an error:
console.log(a); // undefined
var a = 5;let and const are hoisted too, but stay in a temporal dead zone until their declaration actually runs, so accessing them early throws instead of silently giving undefined:
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 5;That error is a feature: it surfaces a real bug (using a variable before it's meant to exist) instead of hiding it behind an undefined.
What to actually use
Default to const for everything. Switch to let only for variables you know will be reassigned, like a loop counter or a running total. Avoid var in new code entirely — its function-scoping and silent hoisting behavior are the source of enough subtle bugs that every modern style guide disallows it.
The next lesson looks at the data types those variables actually hold.