DevPrep
  • Interview Prep
  • Projects
  • Resources
  • Pricing
  • About Us
Submit Question
DevPrep
  • Pricing
  • About Us
Submit Question
  1. Home
  2. Articles
  3. Frontend Engineering
  4. var vs let vs const in JavaScript — What to Actually Use in 2025
XLinkedInReddit
MediumFrontend Engineering

var vs let vs const in JavaScript — What to Actually Use in 2025

D
DevPrep Team
February 9, 2026·3 min read·0
Table of Contents
  • The Key Differences at a Glance
  • 1. Scoping — The Most Important Difference
  • 2. Hoisting and the Temporal Dead Zone (TDZ)
  • 3. const Doesn't Mean Immutable
  • Real Production Issues
  • Issue 1: The Classic Loop Bug
  • Issue 2: Accidental Global Variables
  • Issue 3: Re-declaration Bugs
  • Best Practices for 2025
  • What Google's Style Guide Says
  • Interview Tip

Written by Rahul · Frontend Engineer at Google · Updated 2025

Let me save you 10 minutes: use const by default, let when you need to reassign, never use var. But understanding why is what makes you a strong engineer and helps you debug legacy code. Let's dig in.

The Key Differences at a Glance

Featurevarletconst
ScopeFunctionBlockBlock
HoistingYes (initialized to undefined)Yes (but TDZ)Yes (but TDZ)
Re-declaration✅ Allowed❌ Error❌ Error
Re-assignment✅ Allowed✅ Allowed❌ Error
Global object property✅ Yes❌ No❌ No

1. Scoping — The Most Important Difference

// var is FUNCTION scoped
function example() {
  if (true) {
    var x = 10;
  }
  console.log(x); // 10 — var "leaks" out of the if block
}

// let and const are BLOCK scoped
function example2() {
  if (true) {
    let y = 10;
    const z = 20;
  }
  console.log(y); // ReferenceError!
  console.log(z); // ReferenceError!
}

This is why var causes bugs. It ignores blocks (if, for, while) and only respects function boundaries.

2. Hoisting and the Temporal Dead Zone (TDZ)

// var hoists AND initializes to undefined
console.log(a); // undefined (not an error!)
var a = 5;

// let hoists but does NOT initialize — TDZ
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 5;

// const — same TDZ behavior
console.log(c); // ReferenceError
const c = 5;

The Temporal Dead Zone is the period between entering the scope and the declaration line. let and const exist in this zone but can't be accessed — giving you a clear error instead of a silent undefined.

3. const Doesn't Mean Immutable

This trips up so many people:

const user = { name: "Rahul", age: 28 };
user.age = 29; // ✅ This works! You're mutating the object, not reassigning

user = { name: "Someone" }; // ❌ TypeError: Assignment to constant variable

const numbers = [1, 2, 3];
numbers.push(4); // ✅ Works — array is mutated, not reassigned
numbers = [5, 6]; // ❌ TypeError

const prevents reassignment of the variable binding, not mutation of the value. If you need true immutability, use Object.freeze().

Real Production Issues

Issue 1: The Classic Loop Bug

// ❌ Bug with var
for (var i = 0; i < 5; i++) {
  document.getElementById(`btn-${i}`).addEventListener("click", () => {
    alert(`Button ${i} clicked`); // Always shows "Button 5 clicked"
  });
}

// ✅ Fix with let
for (let i = 0; i < 5; i++) {
  document.getElementById(`btn-${i}`).addEventListener("click", () => {
    alert(`Button ${i} clicked`); // Correct: shows 0, 1, 2, 3, 4
  });
}

Issue 2: Accidental Global Variables

function processData() {
  for (var i = 0; i < 100; i++) {
    // process...
  }
  // "i" is now 100 and accessible here
  // In non-strict mode, if you forget "var", it becomes a GLOBAL variable!
}

// With let, this is impossible:
function processDataSafe() {
  for (let i = 0; i < 100; i++) {
    // process...
  }
  // "i" doesn't exist here — block scoped
}

Issue 3: Re-declaration Bugs

// var allows silent re-declaration — source of bugs
var config = loadConfig();
// ... 200 lines later ...
var config = "oops"; // No error! Original config is gone

// let catches this immediately
let config = loadConfig();
// ... 200 lines later ...
let config = "oops"; // SyntaxError: Identifier 'config' has already been declared

Best Practices for 2025

  1. Default to const — if you don't need to reassign, use const. It communicates intent.
  2. Use let only when reassignment is needed — loop counters, accumulators, conditionally assigned values
  3. Never use var — there's zero reason in modern JavaScript. ESLint rule: no-var
  4. Always use strict mode — catches accidental globals
  5. When working with legacy code, refactor var to const/let carefully — check for hoisting dependencies

What Google's Style Guide Says

Google's internal JavaScript style guide (and the public one) says: "Declare all local variables with either const or let. Use const by default, unless a variable needs to be reassigned. The var keyword must not be used."

Interview Tip

Don't just list the differences. Show the loop bug, explain TDZ, and mention that const doesn't mean immutable. Interviewers love when you can explain why each difference matters in practice.

Related Articles

MediumFrontend Engineering

System Design #12: Design a Multi-Step Form Wizard

7 min read
MediumFrontend Engineering

Mastering Senior-Level JavaScript Interview Concepts

2 min read
MediumFrontend Engineering

System Design #9: Design a Collaborative Text Editor

9 min read

Comments (0)

Sign in to leave a comment.

No comments yet. Be the first to comment.

Table of Contents

  • The Key Differences at a Glance
  • 1. Scoping — The Most Important Difference
  • 2. Hoisting and the Temporal Dead Zone (TDZ)
  • 3. const Doesn't Mean Immutable
  • Real Production Issues
  • Issue 1: The Classic Loop Bug
  • Issue 2: Accidental Global Variables
  • Issue 3: Re-declaration Bugs
  • Best Practices for 2025
  • What Google's Style Guide Says
  • Interview Tip

Series

View all Frontend Engineering articles →

Practice

  • JavaScript
  • DSA
  • Machine Coding
  • System Design

Resources

  • Learning Tracks
  • Articles
  • Roadmaps
  • Compare Concepts
  • Glossary
  • Developer Tools
  • All Questions

Company

  • About
  • Pricing

Legal

  • Privacy Policy
  • Terms of Service
DevPrep

© 2026 DevPrep. All rights reserved.