Understanding the Difference Between let and var in JavaScript

CODE

Recently, I took a technical test for a front-end developer position, and one of the questions asked about the difference between let and var. I was sure I had learned this when I first started programming years ago, but when faced with the question, I couldn’t give a clear answer.

It reminded me that it’s always important to keep the basics fresh in our minds. So, I took this opportunity to revisit let and var, and in this post, I’ll break down their differences in a simple and practical way.

Characteristics of var

var has been around since before ES6 and has the following characteristics:

Works with Function Scope

Variables declared with var follow function scope. Even if you declare them inside a block {}, they are still accessible outside of it.

function example() {
  if (true) {
    var x = 10;
  }
  console.log(x); // 10 (Accessible even outside the block)
}
example();

Affected by Hoisting

var is hoisted, meaning its declaration is moved to the top of its scope automatically. However, only the declaration is hoisted, not the initialization.

function example() {
  console.log(y); // undefined (No error, but undefined)
  var y = 20;
  console.log(y); // 20
}
example();

In this example, y is declared at the top due to hoisting, but its value is assigned later. That’s why accessing it before initialization gives undefined.

Characteristics of let

Introduced in ES6, let was designed to fix some of var‘s issues.

Works with Block Scope

Variables declared with let are only valid within the block {} they are declared in.

function example() {
  if (true) {
    let a = 10;
  }
  console.log(a); // ReferenceError (Outside block scope)
}
example();

Hoisted but with a Temporal Dead Zone (TDZ)

let is also hoisted, but it has a Temporal Dead Zone (TDZ), meaning accessing it before its declaration results in an error.

function example() {
  console.log(b); // ReferenceError (Accessed before declaration)
  let b = 30;
  console.log(b);
}
example();

Unlike var, which would return undefined, let gives a ReferenceError, making it safer by preventing accidental use before declaration.

Is There Any Case Where var Should Be Used?

In modern JavaScript development, using var is no longer recommended. In almost all cases, let or const is the better choice.

That said, you may still encounter var in legacy codebases or when maintaining older projects. So, understanding how it works is still useful!

Why You Should Use let in Practice

Let’s take a real-world example to see why let is the better choice.

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1000);
}
// Output: 3, 3, 3 (Not what we expect)

Here, all three logs print 3 because var has function scope. By the time the setTimeout function runs, the loop has already completed, and i is now 3.

Using let solves this issue:

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1000);
}
// Output: 0, 1, 2 (Works as expected)

Because let has block scope, each iteration of the loop gets its own i, preserving the expected behavior. This is one of the main reasons to always prefer let.

Conclusion

Featurevarlet
ScopeFunction scopeBlock scope
HoistingYes (returns undefined)Yes (TDZ applies)
RedeclarationAllowedNot allowed
UsageLegacy code compatibilityModern JavaScript
  • Use const by default (if reassignment is not needed).
  • Use let when you need to reassign a variable.
  • Avoid var unless working with legacy code.

Even if you’re not asked about let and var in a test, keeping their differences in mind will help you write cleaner, safer JavaScript!

Copied title and URL