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
Feature | var | let |
---|---|---|
Scope | Function scope | Block scope |
Hoisting | Yes (returns undefined ) | Yes (TDZ applies) |
Redeclaration | Allowed | Not allowed |
Usage | Legacy code compatibility | Modern 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!