var is function-scoped and hoisted, let is block-scoped and reassignable, const is block-scoped and can't be reassigned (but objects can be mutated).
Understanding variable declarations is fundamental to JavaScript, especially when maintaining or reading older code.
var is the original way to declare variables. It's function-scoped (not block-scoped), meaning a var inside an if block is accessible outside it. It's also hoisted—declarations are moved to the top of their scope—so you can reference a var before its declaration (though it's undefined until assigned). These behaviors cause subtle bugs.
let was introduced in ES6 and is block-scoped. A let inside an if block stays in that block. It's not hoisted in the same way—accessing it before declaration causes a ReferenceError (the "temporal dead zone"). You can reassign let variables.
const is also block-scoped but cannot be reassigned after initialization. However, const objects and arrays can still be mutated (you can push to a const array, add properties to a const object). For true immutability, you need Object.freeze() or immutability libraries.
Modern best practice: use const by default, let when you need reassignment, and avoid var entirely. This makes code more predictable—you can trust that a const won't change reference, making it easier to reason about data flow.
var is function-scoped and hoisted, let is block-scoped and reassignable, const is block-scoped and can't be reassigned (but objects can be mutated).
Join our network of elite AI-native engineers.