Use let when a variable must be reassigned but should stay inside its nearest enclosing block. Unlike var, it does not escape an if block or loop. If a binding never needs reassignment, use const instead.
How do let and var differ?
The main difference is scope: let is block-scoped, while var is scoped to the nearest function—or, when there is no function, to the applicable module or script/global context. A block is code inside braces, such as the body of an if statement or a loop. Ordinary blocks do not limit a var declaration.
As an Amazon Associate I earn from qualifying purchases.
| Behavior | let |
var |
|---|---|---|
| Scope | Nearest enclosing block, function, module, or script global scope, as applicable | Nearest function, module, or script global scope, as applicable; ordinary blocks do not contain it |
| Read before declaration is reached | Throws ReferenceError during the temporal dead zone |
Returns undefined before initializer assignment |
| Duplicate declaration in the same scope | Syntax error | Allowed |
| Top-level declaration in a classic script | Does not create a property on globalThis |
Creates a property on the global object |
These global-object details apply to classic scripts. Top-level declarations in ECMAScript modules and Node.js CommonJS modules are scoped to their module. MDN’s let reference and var reference describe these distinctions.
Why does block scope help?
A variable declared with let inside a block is available only there. That keeps loop counters and other temporary values from being accessible in surrounding code, reducing the scope in which a name can be used or accidentally changed.
#1 Best Overall
for (let i = 0; i < 3; i++) {
// i is scoped to this loop.
}
// i is not available here.
for (var j = 0; j < 3; j++) {
// j is scoped to the nearest function or applicable script/module context.
}
// j remains available in that surrounding scope.
The example shows scope, not a rule that every var becomes a browser global. Module context matters.
What happens before a declaration runs?
A let binding exists from the start of its scope, but it cannot be accessed until execution reaches its declaration and initialization. The interval before then is called the temporal dead zone; trying to read the binding in that interval throws a ReferenceError.
Rank #2
console.log(count); // ReferenceError
let count = 1;
A var binding is initialized to undefined before its assignment runs, so reading it earlier does not produce that same error:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsconsole.log(count); // undefined
var count = 1;
The error from let can make some ordering mistakes visible sooner, but it does not prevent every bug.
Why does redeclaration matter?
Declaring the same name twice with let in one scope is a syntax error. This can expose a naming mistake rather than silently accepting the second declaration. Duplicate var declarations in the same scope are allowed.
let status = "ready";
let status = "busy"; // SyntaxError
Reassignment is different from redeclaration: let permits assigning a new value to an existing binding.
Rank #4
let status = "ready";
status = "busy"; // Allowed
When should you use const instead?
Choose const when the binding will not be reassigned. MDN notes that many style guides, including its own, recommend const whenever a variable is not reassigned in its scope. Like let, const is block-scoped.
const prevents reassignment of the binding, not changes to an object the binding refers to:
Best Value
const settings = { theme: "light" };
settings.theme = "dark"; // Allowed
settings = {}; // TypeError
MDN explains this distinction in its JavaScript language overview.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Is let always better than var?
For modern JavaScript, let is generally the clearer choice when a value must change: its block scope matches common uses such as loop counters, and its temporal-dead-zone and redeclaration rules catch some mistakes. MDN says that var declarations can have surprising behaviors because they are not block-scoped and are discouraged in modern JavaScript code.
That is a clarity and error-detection case, not a claim that let runs faster or eliminates bugs. Use let for a reassigned, block-limited binding, const for a binding that is not reassigned, and reserve var for code that specifically needs its older scoping behavior.
Recommended Free Tools
References: MDN: let, MDN: var, MDN: JavaScript language overview, and MDN: Grammar and types.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




