let vs const vs var: The Complete Guide

Understanding the differences between JavaScript variable declarations and when to use each.

Quick Summary

Feature var let const
Scope Function Block Block
Hoisting Yes (undefined) Yes (TDZ) Yes (TDZ)
Reassignment Yes Yes No
Redeclaration Yes No No

var - The Old Way

var was the original way to declare variables in JavaScript.

var name = 'John';
var name = 'Jane'; // No error - redeclaration allowed
name = 'Bob';      // Reassignment allowed

Problems with var

1. Function Scope (not Block Scope)

if (true) {
  var x = 10;
}
console.log(x); // 10 - var "leaks" out of blocks

2. Hoisting Issues

console.log(y); // undefined (not an error!)
var y = 5;

3. Loop Variable Leaking

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Outputs: 3, 3, 3 (not 0, 1, 2!)

let - Block Scoped Variable

let was introduced in ES6 (2015) to fix var's problems.

let age = 30;
// let age = 25; // Error: Cannot redeclare
age = 25;        // OK: Can reassign

Benefits of let

1. Block Scope

if (true) {
  let x = 10;
}
// console.log(x); // Error: x is not defined

2. No Hoisting Issues

// console.log(z); // Error: Cannot access before initialization
let z = 5;

3. Works Correctly in Loops

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Outputs: 0, 1, 2 (correct!)

const - Constant Reference

const creates a constant reference to a value.

const PI = 3.14159;
// PI = 3.14; // Error: Cannot reassign

const user = { name: 'John' };
user.name = 'Jane';  // OK: Can modify properties
// user = {};        // Error: Cannot reassign reference

Important: const ≠ Immutable

const arr = [1, 2, 3];
arr.push(4);        // OK: [1, 2, 3, 4]
arr[0] = 99;        // OK: [99, 2, 3, 4]
// arr = [5, 6, 7]; // Error: Cannot reassign

For truly immutable objects, use Object.freeze().

Best Practices

  1. Default to const - Use const for all variables that won't be reassigned
  2. Use let when needed - Only use let if the variable will be reassigned
  3. Avoid var - There's no good reason to use var in modern JavaScript
// Good practice
const API_URL = 'https://api.example.com';
const users = [];

let count = 0;
count++;

// Bad practice
var globalVar = 'avoid this';

Temporal Dead Zone (TDZ)

Both let and const have a "temporal dead zone" - the period between entering a scope and the variable being declared.

{
  // TDZ starts
  // console.log(x); // Error!
  let x = 10;      // TDZ ends
  console.log(x);  // 10
}

Conclusion

  • Use const by default
  • Use let only when you need to reassign
  • Never use var in new code