-
Hajipur, Bihar, 844101
JavaScript is one of the most widely used programming languages today. Whether you are building a website, a mobile app, or even server-side applications, chances are you’ll run into JavaScript at some point. And one of the first things every JavaScript developer learns is how to declare variables.
But here’s where many learners get confused: Should you use var, let, or const?
At first, they all look very similar. You can declare variables with any of them, assign values, and work with those values in your program. But once you dive deeper, you discover that these keywords behave differently in terms of scope, hoisting, mutability, and best practices.
In this blog, we’re going to unpack the whole story. We’ll start with a bit of history about how JavaScript evolved, dive deep into each keyword (var, let, const), explain their quirks with examples, and then move on to practical, real-world use cases. By the end, you’ll not only understand the technical differences but also have clear guidelines on which one to use in modern JavaScript development.
So let’s begin.
When JavaScript was created in 1995 by Brendan Eich, it was built in just 10 days. At the time, the language was meant to be simple and lightweight, something that could run inside browsers alongside HTML.
In those early days, JavaScript had just one way to declare variables: var.
For a while, this worked fine. But as JavaScript grew from small scripts into full-fledged web applications, the quirks of var became major issues. Developers found themselves debugging weird behavior caused by:
Variables leaking out of loops and blocks.
Accidental overwrites because var allowed re-declarations.
Confusing results because of hoisting.
By 2015, JavaScript had matured. The introduction of ES6 (ECMAScript 2015) was a huge milestone. It brought modern features like arrow functions, classes, modules, promises—and two new ways to declare variables: let and const.
The purpose of let and const was simple: fix the problems of var and give developers tools that matched modern coding practices.
var in JavaScript?Let’s start with the oldest one: var.
var name = "Alice";
Scope of var in JavaScript
Variables declared with var are scoped to the nearest function, not to the nearest block.
Example:
function greet() {
if (true) {
var message = "Hello!";
}
console.log(message); // "Hello!" ✅
}
greet();
Even though message was declared inside an if block, it’s still accessible outside of it. This is because var only respects function boundaries, not block boundaries.
var Hoisting in JavaScript
All var declarations are “hoisted” to the top of their scope. That means you can reference a variable before it’s declared, though the value will be undefined.
console.log(a); // undefined
var a = 10;
What actually happens behind the scenes:
var a;
console.log(a); // undefined
a = 10;
This can cause bugs if you expect variables to exist only after the declaration line.
var Re-declaration
With var, you can declare the same variable multiple times in the same scope.
var x = 1;
var x = 2;
console.log(x); // 2
In large codebases, this can overwrite variables unintentionally.
Global Object Binding
Declaring a var outside of any function attaches it to the global object (in browsers, window).
var globalVar = "test";
console.log(window.globalVar); // "test"
This pollutes the global scope and can clash with other scripts.
let in JavaScript?The let keyword was introduced with ES6 to solve most of var’s problems.
let age = 25;
Block Scope
Variables declared with let are restricted to the block {} where they are defined.
if (true) {
let city = "Delhi";
console.log(city); // "Delhi"
}
console.log(city); // ReferenceError ❌
This prevents variables from leaking outside of loops, conditionals, and other blocks.
Hoisting with Temporal Dead Zone (TDZ)let is also hoisted, but it stays uninitialized until the declaration line is reached. If you try to use it before that, you get an error.
console.log(score); // ReferenceError ❌
let score = 100;
This behavior is called the Temporal Dead Zone and is designed to prevent accidental usage before declaration.
No Re-declaration in Same Scope
Unlike var, you cannot declare the same variable twice with let in the same scope.
let color = "red";
let color = "blue"; // SyntaxError ❌
Re-assignment Allowed
You can update the value of a let variable.
let count = 1;
count = 2; // Works fine
const in JavaScript?const is like let, but stricter. It’s designed for values that should not be reassigned.
const pi = 3.14159;
Block Scope
Just like let, variables declared with const are limited to the block they’re in.
Must Be Initialized Immediately
Unlike var and let, you must assign a value when declaring a const.
const country; // SyntaxError ❌
No Re-assignment
You cannot reassign a new value to a const variable.
const name = "Alice";
name = "Bob"; // TypeError ❌
Objects and Arrays Are Mutable
Declaring an object or array with const doesn’t make it completely frozen. It just means the variable cannot be reassigned.
const user = { name: "Sam" };
user.name = "Alex"; // Allowed ✅
const numbers = [1, 2, 3];
numbers.push(4); // Allowed ✅
What’s not allowed:
user = { name: "John" }; // TypeError ❌
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// Output: 3, 3, 3
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// Output: 0, 1, 2
With var, the same variable is shared across all iterations. With let, each iteration gets its own copy.
for (var i = 1; i <= 3; i++) {
document.body.innerHTML += `<button id="btn${i}">Button ${i}</button>`;
document.getElementById(`btn${i}`).addEventListener("click", function () {
alert("You clicked button " + i);
});
}
// Every button shows "You clicked button 4"
Using let fixes the problem:
for (let i = 1; i <= 3; i++) {
document.body.innerHTML += `<button id="btn${i}">Button ${i}</button>`;
document.getElementById(`btn${i}`).addEventListener("click", function () {
alert("You clicked button " + i);
});
}
// Each button shows its correct number
const API_URL = "https://api.example.com";
const TIMEOUT = 5000;
Since these values should not change, const is the best choice.
let seconds = 0;
setInterval(() => {
seconds++;
console.log("Elapsed:", seconds, "seconds");
}, 1000);
Here let is appropriate because seconds changes over time.
const cart = [];
function addItem(item) {
cart.push(item);
console.log(cart);
}
addItem("Apple");
addItem("Orange");
Even though cart is declared as const, we can still modify the contents. The array reference stays the same.
Using var inside loops and expecting each iteration to have its own variable.
Forgetting const objects are mutable, assuming they’re completely frozen.
Declaring variables at the top of scripts with var, unintentionally polluting the global scope.
Shadowing variables by declaring a let or const inside a block with the same name as an outer variable.
Use const by default.
Most variables don’t need reassignment. This makes code cleaner and safer.
Use let only when necessary.
Loop counters, state variables, and accumulators are common cases.
Avoid var in new code.
Unless you’re working in legacy codebases, stick to let and const.
Keep scope tight.
Declare variables in the smallest scope possible to avoid collisions.
Follow team conventions.
Many teams enforce const by default through ESLint rules.
ESLint: Rules like prefer-const encourage developers to use const unless reassignment is necessary.
Prettier: Doesn’t enforce variable keywords directly but works well with ESLint setups.
React and Vue: In React hooks, constants are often used for stable values, while state variables use let internally.
Node.js: Modern Node projects use const for requires/imports and let for mutable variables.
const counterApp = (() => {
let count = 0;
return {
increment: () => {
count++;
console.log("Count:", count);
},
reset: () => {
count = 0;
console.log("Count reset");
}
};
})();
counterApp.increment(); // Count: 1
counterApp.increment(); // Count: 2
counterApp.reset(); // Count reset
Here:
count is declared with let because it changes.
The app object is a const because it should never be reassigned.
So, after all this exploration, the conclusion is clear:
Use const by default. It signals that the variable shouldn’t change, leading to safer code.
Use let when reassignment is required. Great for counters, state trackers, or values that evolve.
Avoid var unless working with old code. Its quirks make it error-prone and unnecessary in modern projects.
By following these simple guidelines, you’ll write JavaScript that’s cleaner, more predictable, and easier to maintain.
The difference between var, let, and const mainly comes down to scope, hoisting, and reassignment. The var keyword is function-scoped, can be re-declared, and is hoisted, which often leads to unexpected results. The let keyword is block-scoped and allows reassignment but does not allow re-declaration in the same scope. On the other hand, the const keyword is also block-scoped but must be initialized immediately and cannot be reassigned after its initial declaration.
In modern JavaScript development, you should generally avoid using var because of its function scope and hoisting behavior. Instead, use let when you need to reassign values within your code, and use const when you want to declare variables whose values should remain constant. This approach ensures cleaner, safer, and more predictable code.
const is often preferred over let because it prevents accidental reassignment and makes the code easier to read and maintain. When you declare a variable with const, you are clearly communicating that the variable will not change, which helps avoid unintended bugs. Many developers use const by default and only switch to let if a variable’s value genuinely needs to be updated.
A common misconception is that const variables cannot change at all. In reality, a const variable cannot be reassigned to a new value, but if it holds a reference to an object or an array, the contents of that object or array can still be modified. For example, you can push elements into a const array or update the properties of a const object.
While var still exists in JavaScript for backward compatibility and can be found in older codebases, it is no longer recommended for modern projects. Since the release of ES6, let and const have become the standard choices for variable declaration. Using them avoids many of the pitfalls associated with var and results in more robust and maintainable code.
Hi, I’m Bikki Singh, a website developer and coding language trainer. I’ve been working on web projects and teaching programming for the past few years, and through CodePractice.in I share what I’ve learned. My focus is on making coding simple and practical, whether it’s web development, Python, PHP, MySQL, C, C++, Java, or front-end basics like HTML, CSS, and JavaScript. I enjoy breaking down complex topics into easy steps so learners can actually apply them in real projects.
31 December 2025
Tired of tutorial hell? Master this daily coding practice routine for beginners. Learn how to stay consistent, how many hours to code daily, and get a roadmap.
18 December 2025
Step-by-step coding roadmap for college students: Practice programming daily, master data structures and algorithms, complete projects, and get placement-ready.
09 December 2025
Learn C programming from scratch with this step-by-step guide. Covers basics, syntax, data types, loops, functions, pointers, arrays, and practice examples.
19 August 2025
Learn HTML semantic tags with examples. Boost SEO, accessibility, and code clarity with this beginner-friendly guide to HTML5 semantic elements.
15 September 2025
Bootstrap vs Tailwind in 2025: Compare coding examples, pros and cons, performance, and real-world use cases to pick the best CSS framework for your project.
28 August 2025
Learn what OOP in C++ is through clear real-life examples. Understand classes, inheritance, encapsulation & more. Start coding smarter today!
Submit Your Reviews