javascript
var
let

What is the difference between "let" and "var"?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In modern JavaScript, both let and var declare variables, but they follow different scoping and hoisting rules. The difference matters because var often allows bugs that let prevents, especially inside loops, conditionals, and larger functions.

Scope: function scope versus block scope

var is function-scoped. let is block-scoped. That is the biggest practical difference.

javascript
1function withVar() {
2  if (true) {
3    var count = 1;
4  }
5
6  console.log(count); // 1
7}
8
9function withLet() {
10  if (true) {
11    let count = 1;
12  }
13
14  // ReferenceError
15  console.log(count);
16}

With var, the variable exists throughout the entire function, even though it was written inside the if block. With let, the variable only exists inside that block.

That makes let a safer default because the lifetime of the variable matches the visible structure of the code.

Hoisting and the temporal dead zone

Both var and let are hoisted, but they behave differently before initialization.

javascript
console.log(total); // undefined
var total = 5;

With var, the declaration is hoisted and initialized to undefined.

With let, the variable exists but cannot be used before the declaration line:

javascript
// ReferenceError
console.log(total);
let total = 5;

This period before initialization is called the temporal dead zone. It is a good thing because it catches mistakes earlier instead of silently giving you undefined.

Re-declaration rules

var allows re-declaration in the same scope:

javascript
var name = "Ava";
var name = "Liam";
console.log(name); // Liam

let does not:

javascript
let name = "Ava";
// SyntaxError
let name = "Liam";

This rule makes accidental duplicate declarations easier to spot during development.

Loop behavior is often where bugs appear

Classic loop bugs are one of the strongest arguments for let.

javascript
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log("var:", i), 0);
}

That prints 3 three times, because all callbacks close over the same function-scoped i.

Now compare it with let:

javascript
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log("let:", i), 0);
}

That prints 0, 1, and 2, because each loop iteration gets its own block-scoped binding.

Global behavior

A global var declaration becomes a property of the browser window object. A global let declaration does not.

javascript
1var oldStyle = 1;
2let modernStyle = 2;
3
4console.log(window.oldStyle);    // 1
5console.log(window.modernStyle); // undefined

This is another reason let behaves more predictably in modern applications.

When to use each one

For current JavaScript code, let is generally preferred over var. In many cases, const is even better when the binding should not be reassigned.

Use let when:

  • the variable will be reassigned,
  • the variable should exist only in a specific block,
  • or you want safer, modern scoping behavior.

Use var mainly when maintaining older code or when you deliberately need its historical function-scoped behavior, which is rare in new code.

Common Pitfalls

The biggest mistake is assuming var respects block boundaries. It does not. Variables declared with var inside if, for, or while still leak to the surrounding function scope.

Another common issue is using a let variable before the declaration line and expecting undefined. Instead, JavaScript throws a ReferenceError because of the temporal dead zone.

Be careful not to confuse "can be reassigned" with "can be redeclared." let allows reassignment but not re-declaration in the same scope.

Finally, if you are writing new code, do not stop at choosing between var and let. Also ask whether the variable should actually be const, because that communicates intent even more clearly.

Summary

  • 'var is function-scoped, while let is block-scoped.'
  • 'var is hoisted and initialized to undefined; let is hoisted but inaccessible before initialization.'
  • 'var allows re-declaration in the same scope; let does not.'
  • 'let behaves correctly in loop closures and avoids many old JavaScript scoping bugs.'
  • In modern code, prefer let over var, and prefer const when reassignment is not needed.

Course illustration
Course illustration

All Rights Reserved.