Understanding JavaScript Variables: var, let, and const

Variables are the foundation of any JavaScript program. They let you store, update, and reference data throughout your code. JavaScript gives you three keywords for declaring variables: var, let, and const. Knowing when and why to use each one will save you from confusing bugs and make your code easier to read.

The Old Way: var

var has been part of JavaScript since the very beginning. While it still works, it has some quirky behaviors that can trip up developers:

  • Function-scoped: A var variable is accessible anywhere within the function it's declared in — not just the block (like an if statement or loop).
  • Hoisted: var declarations are moved to the top of their scope during execution. The variable exists before its declaration line runs, but its value is undefined until that line is reached.
  • Can be re-declared: You can declare the same variable name twice with var in the same scope without any error.
var greeting = "Hello";
var greeting = "Hi"; // No error — works fine with var
console.log(greeting); // "Hi"

The Modern Way: let

Introduced in ES6 (2015), let solves most of var's problems:

  • Block-scoped: A let variable only exists within the curly braces {} where it's declared.
  • Not re-declarable: Trying to declare the same name twice in the same scope throws an error.
  • Can be reassigned: You can change its value after declaration.
let score = 0;
score = 10; // Allowed
console.log(score); // 10

if (true) {
  let innerVar = "only here";
}
console.log(innerVar); // ReferenceError — not accessible outside the block

Constants: const

const is like let but with one key restriction — you cannot reassign it after the initial assignment:

  • Block-scoped: Same scoping rules as let.
  • Must be initialized: You must assign a value when you declare it.
  • Cannot be reassigned: Attempting to reassign a const throws a TypeError.
const PI = 3.14159;
PI = 3; // TypeError: Assignment to constant variable.

Important: const doesn't make objects or arrays immutable — it just prevents the variable from pointing to a different object. The object's contents can still change:

const user = { name: "Alice" };
user.name = "Bob"; // Allowed — we're modifying the object, not reassigning user
console.log(user.name); // "Bob"

Quick Comparison Table

Featurevarletconst
ScopeFunctionBlockBlock
HoistedYes (undefined)Yes (not initialized)Yes (not initialized)
Re-declarableYesNoNo
ReassignableYesYesNo

Which Should You Use?

  1. Default to const — use it whenever you don't need to reassign the variable. This signals intent clearly to anyone reading your code.
  2. Use let when you know the variable's value will change (like a loop counter or accumulator).
  3. Avoid var in modern JavaScript. Its quirky scoping behavior adds unnecessary complexity.

Conclusion

Choosing the right variable declaration keyword is a small habit that leads to much cleaner, less buggy code. Start with const, reach for let when needed, and leave var in the past where it belongs.