Skip to main content
โšก Calmops

JavaScript Variables: var, let, const Explained

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
}

Official Documentation

External Resources

Summary

  • Use const by default for values that won’t change
  • Use let when you need to reassign a variable
  • Avoid var in modern JavaScript
  • Understand block scope vs function scope
  • Remember that const prevents reassignment, not modification

Next Steps

  1. JavaScript Data Types Fundamentals
  2. Functions: Definition, Parameters, Return Values
  3. Scope and Hoisting in JavaScript
  4. Closures: Understanding Function Scope

Comments