SKU // 58

var, let, and const

JavaScript has three ways to declare a variable. You met each one early on; now that you understand scope and hoisting, this lesson puts them side by side so you can choose correctly and read older code with confidence.

// The Full Comparison

var let const
ScopeFunctionBlockBlock
ReassignYesYesNo
Redeclare in same scopeYes (silently)NoNo
Use before declaringundefinedErrorError
Must initializeNoNoYes
Global becomes window propertyYesNoNo
Introduced19952015 (ES6)2015 (ES6)

// Problem 1: var Leaks Out of Blocks

function checkout(items) {
  for (var i = 0; i < items.length; i++) {
    var price = items[i];
  }
  console.log(i, price);   // both still exist after the loop
}

checkout([4, 9, 2]);
3 2

With let, both lines would throw an error, because i and price would stay inside the loop where they belong.

// Problem 2: var Allows Silent Redeclaring

var total = 100;
// ...200 lines later, someone reuses the name...
var total = 0;           // no warning; the first total is gone

let count = 1;
let count = 2;           // SyntaxError: Identifier 'count' has already been declared
SyntaxError: Identifier 'count' has already been declared

// Problem 3: var Pollutes the Global Object

In a browser, a top-level var becomes a property of window, where it can collide with built-in names:

var appName = "Lab";
let appMode = "dev";

console.log(window.appName);   // "Lab"
console.log(window.appMode);   // undefined
Lab undefined
Real Bug
var name = 42; at the top level in a browser does not give you the number 42. window.name is a built-in property that always stores a string, so you get "42". With let you get the number you expect.

// Problem 4: Loops with Delayed Callbacks

Covered in Code Blocks: var gives every loop pass the same shared variable, so timers and event handlers created in the loop all see its final value. let gives each pass its own.

Watch out: chained assignment
let a = b = "unknown"; looks like it declares two variables, but let only applies to a. The b = "unknown" part assigns to an undeclared b, which quietly becomes an automatic global (or a ReferenceError in strict mode). W3Schools uses exactly this line in its var/let/const example. Declare each variable separately: let a = "unknown"; let b = "unknown";.

// How to Choose

  1. Start with const. Most values never need to be reassigned
  2. If you find you need to reassign it (a counter, a running total, a value that changes), switch to let
  3. Do not use var in new code
const TAX = 0.08;                 // never changes
const cart = [];                  // contents change, but it is always the same array
let subtotal = 0;                 // reassigned as items are added

for (const price of [5, 12, 3]) {  // const works here: each pass gets a new price
  cart.push(price);
  subtotal += price;
}

console.log(cart, subtotal, (subtotal * (1 + TAX)).toFixed(2));
[5, 12, 3] 20 21.60
Note
const in for...of works because each pass creates a new variable. In a classic for (let i = 0; ...; i++) loop you need let, since i++ reassigns it.

// Reading Older Code

You will still meet var in tutorials, Stack Overflow answers, and older projects. When you do, read it as "function-scoped, hoisted as undefined." When updating such code, swapping var for let or const is usually safe, but check that nothing relied on the variable leaking out of a block.

// Quick Check

Which keyword should be your default choice?

  1. var
  2. let
  3. const
  4. No keyword
Show answer
C. Start with const, and switch to let only when the variable really needs to be reassigned. Avoid var in new code.

What does this log?

if (true) {
  var a = 1;
  let b = 2;
}
console.log(typeof a, typeof b);
Show answer
number undefined. var a leaked out of the block; let b did not. (typeof on a name that does not exist gives "undefined" instead of throwing an error.)

What is wrong with for (const i = 0; i < 3; i++)?

  1. Nothing
  2. i++ reassigns i, which const forbids: TypeError
  3. const cannot be used in a for header at all
  4. It never starts
Show answer
B. The first pass runs, then i++ throws TypeError: Assignment to constant variable. Use let for counters. (const is fine in for...of, where each pass gets a brand-new variable.)

// Try It

  1. Click Open Playground. Rewrite checkout with let and read the new errors
  2. Try redeclaring a variable with var, then with let
  3. Compare window.x after var x = 1 with window.y after let y = 1
  4. Take a small program you wrote earlier and convert every variable to the strictest keyword that still works
// Video Walkthroughs
Last updated: Oct 10, 2026, 12:53 AM ET