Delete var.
It hoists. It leaks scope. It's confusing. There is literally zero reason to use var in 2026. If you see it in a PR, reject it immediately.
The `var` Disaster
var doesn't respect code blocks. It "hoists" itself to the top of the function or global scope, leading to variables existing before you declare them.
// ❌ The Hoisting Nightmare console.log(x); // undefined (Not ReferenceError!) var x = 5; if (true) { var y = 10; } console.log(y); // 10 (Leaked out of the if block!)
02.
Avoid let
The `let` Trap
"But I need to change the value in a loop!"
Do you? Or do you actually need map() or reduce()?
Every time you use let, you introduce state mutation. The value changes over time. This forces your brain to track the state history of a variable as you read the code.
// ❌ Bad (Imperative Mutation) let total = 0; for (const x of items) { total += x.price; // State changes N times! } // ✅ Good (Declarative Expression) const total = items.reduce((acc, x) => acc + x.price, 0);
Deep Dive: Temporal Dead Zone (TDZ)
Unlike var, which hoists as undefined, let and const hoist but are placed in the TDZ until the execution reaches their declaration line.
Accessing them early throws a ReferenceError. This "fail-fast" behavior prevents subtle bugs caused by using variables before they exist.
03.
The const Kingdom
const is a signal to other developers: "This reference will never change." It reduces cognitive load. You define it, assign it, and trust it forever.
Comparison Table
| Keyword | Reassignable? | Scope | Verdict |
|---|---|---|---|
| var | Yes | Function | DELETE |
| let | Yes | Block | USE RARELY |
| const | No | Block | DEFAULT |
04. The Senior Engineer's Take
Reassignment != Mutation
Remember: const prevents reassignment, not mutation of the object content.
const x = [] means you can't say x = somethingElse, but you CAN say x.push(1).
For true immutability, use Object.freeze() or the new Records & Tuples.