You will be able to declare JavaScript variables with let, understand block scope, and choose let over var for safer local variables.
What it is
let declares a variable whose visibility is limited to the nearest enclosing block. A block is any group of statements wrapped in braces, such as a function body, an if statement, a for loop, or a standalone { ... } block. The mental model is simple: a let variable belongs to the place where it is declared, not to the whole function or file.
Related terms include block scope, hoisting, temporal dead zone, redeclaration, const, and var. Like const, let is block scoped. Unlike const, a let variable can be reassigned after declaration. Unlike var, it does not leak into the surrounding function scope.
Why it matters
- It prevents accidental variable leakage from loops and conditionals.
- It makes code easier to reason about because variables are visible only where they are needed.
- It reduces naming collisions in larger functions and modules.
- It supports safer iteration, especially when each loop iteration needs its own counter.
- It aligns with modern JavaScript style, where
constis the default andletis used only when reassignment is required.
Syntax or steps
The smallest useful pattern is to declare a variable, initialize it, and reassign it inside the same block:
let count = 0;
count = count + 1;
You can also declare without an initial value, but the variable remains uninitialized until assigned. Do not redeclare the same name in the same block. If the value will never be reassigned, prefer const.
Example
function tally(items) {
let total = 0;
for (let i = 0; i < items.length; i += 1) {
let item = items[i];
total += item.price;
}
// console.log(i); // ReferenceError: i is not defined
return total;
}
const cart = [
{ price: 10 },
{ price: 25 }
];
console.log(tally(cart)); // 35
Part by part: total is declared with let inside the function, so it can be updated across loop iterations. The loop counter i is declared with let in the for header, so it exists only for the loop. Each iteration also creates a new block-scoped item. After the loop ends, i is no longer accessible, which prevents accidental use of a stale loop variable.
Common mistakes
- Using a variable outside its block. If you declare
let x = 1inside anifblock, it is not available after the block. Fix it by declaringxoutside the block or returning the value. - Redeclaring the same name in the same scope.
let count = 1; let count = 2;throws aSyntaxError. Fix it by using a different name or a different block. - Accessing a variable before its declaration.
letdeclarations are hoisted but not initialized, so early access throws aReferenceError. Fix it by moving the declaration above the use. - Using
letwhen the value never changes. This is not wrong, butconstcommunicates intent better. Fix it by switching toconst.
When to use it
Use let when you need a local variable that changes. Use const when the binding should not be reassigned. Use var mainly when maintaining older code, because its function scope and hoisting behavior can create surprises.
| Keyword | Scope | Reassignment | Best for |
|---|---|---|---|
const | Block | No | Values that should not be reassigned |
let | Block | Yes | Local variables that change |
var | Function or global | Yes | Legacy code only |
Practice
Guided exercise
Declare let score = 0, add 10 to it, then log the result.
let score = 0;
score = score + 10;
console.log(score);
Expected output: 10.
Challenge
Write a loop that logs the numbers 1, 2, and 3 using a block-scoped counter.
for (let i = 1; i <= 3; i += 1) {
console.log(i);
}
Expected output: 1, 2, 3. Hint: the counter i should be declared inside the for header.
Quick check
Question: What happens if you try to read i immediately after a for (let i = 0; ...) loop?
Answer: JavaScript throws a ReferenceError because i is block scoped and no longer exists outside the loop.
Summary
let gives you mutable variables with block scope, making JavaScript code safer and easier to reason about. Prefer const by default, use let when a value must change, and avoid var unless you are working with legacy code.