JavaScript Variables: var, let, const Explained
JavaScript has three ways to declare variables: var, let, and const. Understanding the differences is crucial for writing modern JavaScript.
var: The Old Way
var was the original way to declare variables in JavaScript. It has some quirks that led to the introduction of let and const.
Basic Usage
var name = "Alice";
console.log(name); // "Alice"
Function Scope
var is function-scoped, not block-scoped:
function example() {
if (true) {
var x = 10;
}
console.log(x); // 10 (accessible outside the if block)
}
Hoisting
var declarations are hoisted to the top of their scope:
console.log(y); // undefined (not an error!)
var y = 5;
console.log(y); // 5
This is equivalent to:
var y;
console.log(y); // undefined
y = 5;
console.log(y); // 5
Re-declaration
You can re-declare var variables:
var count = 1;
var count = 2; // No error
console.log(count); // 2
let: Block-Scoped
let was introduced in ES6 (2015) to fix var’s issues. It’s block-scoped and more predictable.
Basic Usage
let name = "Bob";
console.log(name); // "Bob"
Block Scope
let is scoped to the nearest enclosing block (if, for, while, etc.):
function example() {
if (true) {
let x = 10;
}
console.log(x); // ReferenceError: x is not defined
}
Temporal Dead Zone
let variables can’t be accessed before declaration:
console.log(z); // ReferenceError: Cannot access 'z' before initialization
let z = 5;
No Re-declaration
You can’t re-declare let variables in the same scope:
let count = 1;
let count = 2; // SyntaxError: Identifier 'count' has already been declared
But you can in different scopes:
let count = 1;
if (true) {
let count = 2; // Different scope, no error
console.log(count); // 2
}
console.log(count); // 1
const: Block-Scoped and Constant
const is like let, but the variable can’t be reassigned after initialization.
Basic Usage
const PI = 3.14159;
console.log(PI); // 3.14159
Can’t Reassign
const name = "Charlie";
name = "David"; // TypeError: Assignment to constant variable
Must Initialize
const x; // SyntaxError: Missing initializer in const declaration
Objects and Arrays
const prevents reassignment, but doesn’t prevent modification:
const person = { name: "Eve" };
person.name = "Frank"; // OK - modifying property
console.log(person); // { name: "Frank" }
person = {}; // TypeError - can't reassign
const numbers = [1, 2, 3];
numbers.push(4); // OK - modifying array
console.log(numbers); // [1, 2, 3, 4]
numbers = []; // TypeError - can't reassign
Comparison Table
| Feature | var | let | const |
|---|---|---|---|
| Scope | Function | Block | Block |
| Re-declaration | Yes | No | No |
| Reassignment | Yes | Yes | No |
| Hoisting | Yes (undefined) | Yes (TDZ) | Yes (TDZ) |
| Initialization Required | No | No | Yes |
Best Practices
Use const by Default
const name = "Alice"; // Use const for values that won't change
Use let When Reassignment Needed
let count = 0;
count++; // Need to reassign
Avoid var
// Don't do this
var oldStyle = "avoid";
// Do this instead
const newStyle = "prefer";
Real-World Examples
Loop Variables
// Good - let is block-scoped
for (let i = 0; i < 3; i++) {
console.log(i);
}
console.log(i); // ReferenceError
// Bad - var leaks out
for (var j = 0; j < 3; j++) {
console.log(j);
}
console.log(j); // 3 (accessible outside loop)
Configuration
const API_KEY = "secret123";
const DATABASE_URL = "mongodb://localhost";
// These shouldn't change during runtime
Counters
let pageViews = 0;
function trackView() {
pageViews++; // Need to reassign
}
Scope Example
const global = "global scope";
function myFunction() {
const functionScope = "function scope";
if (true) {
const blockScope = "block scope";
console.log(global); // "global scope"
console.log(functionScope); // "function scope"
console.log(blockScope); // "block scope"
}
console.log(blockScope); // ReferenceError
}
Related Resources
Official Documentation
External Resources
Summary
- Use
constby default for values that won’t change - Use
letwhen you need to reassign a variable - Avoid
varin modern JavaScript - Understand block scope vs function scope
- Remember that
constprevents reassignment, not modification
Next Steps
- JavaScript Data Types Fundamentals
- Functions: Definition, Parameters, Return Values
- Scope and Hoisting in JavaScript
- Closures: Understanding Function Scope
Comments