Mapagam
  • JavaScript 
  • Web APIs 
  • TypeScript 
  • React 

How JavaScript Variables Actually Work: var vs let vs const

Posted on April 18, 2025 • 7 min read • 1,306 words
Share via
Mapagam
Link copied to clipboard

Learn the differences between var, let, and const in JavaScript. Master scoping, hoisting, and immutability with real-world examples.

On this page
1. Introduction to JavaScript Variable Declarations 1.1. The Rise of let and const 2. var - The Old School of JavaScript 2.1. Characteristics of var 2.2. Example of var and Hoisting 2.3. Pitfalls of var 3. let - The Modern Approach 3.1. Characteristics of let 3.2. Example of let and Block Scoping 3.3. Pitfalls of let 4. const - Constants in JavaScript 4.1. Characteristics of const 4.2. Example of const 4.3. Mutable Objects with const 5. Comparing var, let, and const 5.1. When to Use var, let, and const 6. Common Mistakes and Pitfalls 6.1. Re-declaring with let and const 6.2. Misunderstanding Block Scope 7. Best Practices for Modern JavaScript 8. Conclusion Key Takeaways:

JavaScript is one of the most popular and versatile programming languages in the world. As a frontend developer, understanding how variables work is fundamental to writing efficient and bug-free code. The way JavaScript handles variables can have a huge impact on your application’s behavior. In this article, we’ll dive deep into the differences between var, let, and const—the three ways to declare variables in JavaScript. By the end of this article, you’ll understand how each works, their differences, and when to use them in real-world scenarios, especially in frameworks like React or TypeScript.

1. Introduction to JavaScript Variable Declarations

In JavaScript, variables are containers for storing data. However, the way these variables are declared and scoped can vary depending on which keyword you use. The three main keywords for declaring variables are var, let, and const. Understanding the differences between these can help prevent bugs, especially in complex applications like those built with React or when using modern JavaScript features.

1.1. The Rise of let and const

Historically, JavaScript only had one way to declare variables—var. However, with the introduction of ES6 (ECMAScript 2015), let and const were introduced to improve the way JavaScript handles variable scoping and immutability. While var is still widely used, the modern best practice is to prefer let and const for declaring variables.

2. var - The Old School of JavaScript

2.1. Characteristics of var

Before ES6, var was the only way to declare a variable. Even though var is still valid JavaScript, it has some quirks that can lead to bugs, especially in large, complex applications. Here’s a breakdown of how var behaves:

  • Function-scoped: A variable declared with var is scoped to the nearest function, not the block of code in which it is declared.
  • Hoisting: var declarations are hoisted to the top of the function or global scope, which means they are initialized with undefined before the execution of the code begins. This can lead to some confusing behavior.

2.2. Example of var and Hoisting

function testVar() {
  console.log(myVar); // undefined
  var myVar = 'Hello, World!';
  console.log(myVar); // 'Hello, World!'
}

testVar();

In the example above, even though the variable myVar is used before it is declared, JavaScript does not throw an error. Instead, it returns undefined because var is hoisted, and the variable is initialized at the top of the function.

2.3. Pitfalls of var

The main issue with var is that it allows variables to be accidentally overwritten, or worse, misused in different scopes. Because var is function-scoped rather than block-scoped, this can lead to unexpected behavior in loops or conditionals.

for (var i = 0; i < 3; i++) {
  console.log(i); // prints 0, 1, 2
}
console.log(i); // prints 3, because `i` is accessible outside the loop

In this case, i is accessible outside the loop because var is function-scoped, not block-scoped.

3. let - The Modern Approach

3.1. Characteristics of let

Introduced in ES6, let allows you to declare variables that are scoped to the nearest block, statement, or expression. This provides more predictable behavior, especially in loops and conditionals. Here’s how let works:

  • Block-scoped: A variable declared with let is scoped to the nearest block (enclosed by curly braces {}), whether it’s a function, loop, or if statement.
  • No Hoisting: Variables declared with let are hoisted, but they are not initialized until the code execution reaches the let declaration. This leads to a temporal dead zone (TDZ), which prevents accessing the variable before it’s declared.

3.2. Example of let and Block Scoping

function testLet() {
  if (true) {
    let myLet = 'Hello, World!';
    console.log(myLet); // 'Hello, World!'
  }
  console.log(myLet); // ReferenceError: myLet is not defined
}

testLet();

In the example above, myLet is scoped to the if block and cannot be accessed outside of it. This is a significant improvement over var, where the variable would have been accessible outside the block.

3.3. Pitfalls of let

Even though let is much safer than var, it still requires attention to detail. For instance, re-declaring a variable within the same scope is not allowed:

let myLet = 'First Declaration';
let myLet = 'Second Declaration'; // SyntaxError: Identifier 'myLet' has already been declared

4. const - Constants in JavaScript

4.1. Characteristics of const

const is used to declare variables that are constant, meaning their values cannot be reassigned after they are initialized. Like let, const is also block-scoped. However, there is one key difference: once a variable is assigned a value with const, that value cannot be changed.

  • Block-scoped: Just like let, const is scoped to the nearest block.
  • Immutable bindings: The value assigned to a const variable cannot be reassigned. However, if the value is an object or array, the contents of the object or array can still be modified (but the reference cannot).

4.2. Example of const

const myConst = 'Hello, World!';
myConst = 'New Value'; // TypeError: Assignment to constant variable

In the example above, trying to reassign a value to myConst will result in an error because it is a constant.

4.3. Mutable Objects with const

If the value assigned to const is an object, the object itself is mutable, but the reference cannot be changed.

const myObj = { name: 'John' };
myObj.name = 'Jane'; // This is allowed
myObj = { name: 'Mike' }; // TypeError: Assignment to constant variable

This behavior often confuses developers new to const, as they may expect the object itself to be immutable.

5. Comparing var, let, and const

Feature var let const
Scope Function-scoped Block-scoped Block-scoped
Hoisting Hoisted (initialized to undefined) Hoisted (TDZ) Hoisted (TDZ)
Reassignable Yes Yes No (immutable reference)
Redeclarable Yes No No

5.1. When to Use var, let, and const

  • Use var: Although var is generally discouraged due to its confusing scoping rules, you may still encounter legacy code or libraries where it’s used. If you’re working with older codebases, understanding var is essential.

  • Use let: Use let when the value of the variable might change later. It’s perfect for loops, conditionals, and situations where reassignment is required.

  • Use const: Use const for values that should not be reassigned. This is ideal for variables that hold references to immutable objects or values, ensuring that they are not accidentally modified.

6. Common Mistakes and Pitfalls

6.1. Re-declaring with let and const

One common pitfall for developers is trying to re-declare a variable using let or const in the same scope. Unlike var, this will throw a SyntaxError.

let x = 10;
let x = 20; // SyntaxError: Identifier 'x' has already been declared

6.2. Misunderstanding Block Scope

Another issue developers face is misunderstanding block scope. Remember, let and const are confined to the block in which they are declared, while var can leak outside the block.

if (true) {
  var foo = 'bar';
  let bar = 'foo';
}

console.log(foo); // 'bar' (accessible globally)
console.log(bar); // ReferenceError: bar is not defined

7. Best Practices for Modern JavaScript

  • Prefer const by default: For most variables, use const unless you explicitly need to reassign the variable. This helps avoid accidental reassignments.
  • Use let when reassigning is needed: If the value of the variable will change, use let. Avoid var due to its scoping issues.
  • Avoid global variables: Always scope your variables as tightly as possible to avoid polluting the global namespace.

8. Conclusion

In summary, the introduction of let and const in ES6 significantly improved the way we handle variables in JavaScript. While var still has its place in legacy code, modern JavaScript development heavily relies on let and const for better control and predictability of variable scoping and immutability.

Key Takeaways:

  • Use var with caution and primarily in legacy codebases.
  • Default to const for all variables unless reassignment is necessary.
  • Use let for variables that require reassignment, especially in loops or conditional blocks.
  • Understanding hoisting and block scoping is essential to avoiding common pitfalls in JavaScript.
JavaScript Variables   Var vs Let vs Const   JavaScript Scoping   Hoisting in JavaScript   JavaScript Best Practices  
JavaScript Variables   Var vs Let vs Const   JavaScript Scoping   Hoisting in JavaScript   JavaScript Best Practices  
 Understanding JavaScript Hoisting Without Confusion
Arrow Functions vs Regular Functions: Which One to Use and When? 

More Reading!

  1. How to Convert Strings to Numbers in JavaScript (And Vice Versa!)
  2. JavaScript Strings Made Easy: Methods, Concatenation & Best Practices
  3. Let vs Var vs Const: Choosing the Right JavaScript Variable
  4. TypeScript Variables: Let, Const, and Var Explained
  5. What Are Variables in JavaScript? A Simple Explanation
On this page:
1. Introduction to JavaScript Variable Declarations 1.1. The Rise of let and const 2. var - The Old School of JavaScript 2.1. Characteristics of var 2.2. Example of var and Hoisting 2.3. Pitfalls of var 3. let - The Modern Approach 3.1. Characteristics of let 3.2. Example of let and Block Scoping 3.3. Pitfalls of let 4. const - Constants in JavaScript 4.1. Characteristics of const 4.2. Example of const 4.3. Mutable Objects with const 5. Comparing var, let, and const 5.1. When to Use var, let, and const 6. Common Mistakes and Pitfalls 6.1. Re-declaring with let and const 6.2. Misunderstanding Block Scope 7. Best Practices for Modern JavaScript 8. Conclusion Key Takeaways:
Follow me

I work on everything coding and technology

   
Mapagam
Mapagam is your go-to resource for all things related to frontend development. From the latest frameworks and libraries to tips, tutorials, and best practices, we dive deep into the ever-evolving world of web technologies.
Licensed under Creative Commons (CC BY-NC-SA 4.0).
 
Frontend
JavaScript 
Web Api 
TypeScript 
React 
Social
Linkedin 
Github 
Mapagam
Code copied to clipboard