Home Module 09 Variables

1. Introduction

A variable is a named container that holds a value. Think of it like a labelled box — you put something in, give the box a name, and then use that name whenever you need the contents.

let score = 0;
// The box is named "score" and currently holds the value 0

score = 10;
// We put a new value (10) in the box

console.log(score); // 10

Variables are fundamental to every program. They let you store user input, track state (like a score or a user's name), do calculations, and refer to the same value in multiple places without repeating it.

JavaScript has three keywords for declaring variables: let, const, and var. Modern JavaScript uses let and const almost exclusively.

2. Theory

2.1 let — a variable that can change

let age = 25;
console.log(age); // 25

age = 26; // Reassign
console.log(age); // 26

let score; // Declared but not assigned
console.log(score); // undefined
  • Can be declared without a value (defaults to undefined).
  • Can be reassigned any number of times.
  • Block-scoped (explained in section 2.5).

2.2 const — a constant that cannot be reassigned

const PI = 3.14159;
console.log(PI); // 3.14159

PI = 3; // TypeError: Assignment to constant variable
const name = 'Alice';
const MAX_SIZE = 100;
const API_URL = 'https://api.example.com';
  • Must be assigned a value at the time of declaration.
  • Cannot be reassigned after declaration.
  • Block-scoped.
  • Use const for values that should not change — it makes your intent clear.
Important: const prevents reassignment, but if the value is an object or array, the contents can still be changed. You will see this in Module 12.

2.3 var — the old way (avoid)

var count = 0;
count = 5;
console.log(count); // 5

var was the only way to declare variables before ES6 (2015). It has confusing behaviour around hoisting and scope that leads to bugs. Always use let or const in modern JavaScript.

You will encounter var in older code and tutorials, so it is useful to recognise it — but do not use it in new code.

2.4 let vs const — which to use?

SituationUse
Value will change (counter, loop variable)let
Value will not change (configuration, calculated result)const
Not sure?Start with const — switch to let if you need to reassign

Many developers default to const for everything and only use let when they know the value must change.

2.5 Block scope

Both let and const are block-scoped — they only exist inside the curly-brace block { } where they are declared.

{
  let message = 'I am inside the block';
  console.log(message); // Works
}
console.log(message); // ReferenceError — message does not exist here

if (true) {
  const greeting = 'Hello';
  console.log(greeting); // Works
}
console.log(greeting); // ReferenceError

You will see the importance of this more clearly when you learn about functions and loops.

2.6 Naming rules and conventions

Rules (enforced by the engine):

  • Must start with a letter, underscore (_), or dollar sign ($).
  • Cannot start with a number.
  • Cannot use reserved keywords (let, const, function, if, etc.).
  • Case-sensitive: name and Name are different variables.
// Valid names
let name = 'Alice';
let _privateValue = 42;
let $price = 9.99;
let camelCaseIsStandard = true;
let count2 = 0;

// Invalid names
let 2fast = false;    // SyntaxError — starts with number
let my-var = 'x';    // SyntaxError — hyphens not allowed
let let = 'bad';     // SyntaxError — reserved keyword

Conventions (style, not enforced):

  • camelCase for regular variables and functions: firstName, totalPrice, getUserName
  • UPPER_SNAKE_CASE for true constants: MAX_RETRIES, API_KEY
  • Use descriptive names: userAge is better than x or a

2.7 Declaring multiple variables

// One per line (recommended — clearest)
let firstName = 'Alice';
let lastName  = 'Smith';
let age       = 30;

// Multiple on one line (acceptable)
let x = 1, y = 2, z = 3;

// With const
const TAX_RATE = 0.2;
const SHIPPING = 5.99;

2.8 Hoisting (important to understand)

JavaScript moves (hoists) variable declarations to the top of their scope before execution. However, let and const are in a "temporal dead zone" — they cannot be accessed before their declaration line:

// var is hoisted and initialised to undefined
console.log(x); // undefined (no error)
var x = 5;

// let/const: hoisted but NOT initialised — accessing them causes ReferenceError
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 5;

This is another reason to avoid var — its hoisting behaviour can make bugs very hard to track down.

3. Real World Example

A shopping cart uses variables to track state:

// Constants — these values don't change
const TAX_RATE   = 0.08;   // 8%
const FREE_SHIPPING_THRESHOLD = 50;

// Variables — these change as the user shops
let cartTotal    = 0;
let itemCount    = 0;
let userName     = '';

// When the user adds an item
function addItem(price) {
  cartTotal = cartTotal + price;
  itemCount = itemCount + 1;

  const tax      = cartTotal * TAX_RATE;
  const shipping = cartTotal >= FREE_SHIPPING_THRESHOLD ? 0 : 5.99;
  const grandTotal = cartTotal + tax + shipping;

  console.log('Items:', itemCount);
  console.log('Subtotal: $' + cartTotal.toFixed(2));
  console.log('Grand total: $' + grandTotal.toFixed(2));
}

addItem(12.99); // Add a $12.99 item
addItem(29.99); // Add another item

4. Code Example

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Variables Demo</title></head>
<body>
  <h1>Variable Demo</h1>
  <button id="counter-btn">Count: 0</button>
  <button id="reset-btn">Reset</button>

  <script>
    // const — will not change
    const MAX_COUNT = 10;

    // let — will change with every click
    let count = 0;

    const counterBtn = document.querySelector('#counter-btn');
    const resetBtn   = document.querySelector('#reset-btn');

    counterBtn.addEventListener('click', function () {
      if (count < MAX_COUNT) {
        count = count + 1;
        counterBtn.textContent = 'Count: ' + count;
      } else {
        counterBtn.textContent = 'Max reached!';
      }
    });

    resetBtn.addEventListener('click', function () {
      count = 0;
      counterBtn.textContent = 'Count: 0';
    });
  </script>
</body>
</html>

5. Code Breakdown

const MAX_COUNT = 10

A constant that defines the ceiling. Using const and UPPER_SNAKE_CASE signals to anyone reading the code that this value is intentionally fixed. If you tried to change it later with MAX_COUNT = 20, JavaScript would throw a TypeError immediately.

let count = 0

A mutable variable starting at zero. let is correct here because count changes every time the button is clicked.

count = count + 1

This is reassignment. It reads the current value of count, adds 1, then stores the result back into count. This is a very common pattern. You will also see the shorthand count += 1 and count++ — both do the same thing.

Scope of counterBtn and resetBtn

These are declared with const at the top level of the script (outside any function or block), so they are accessible anywhere in the script. Keeping references to DOM elements in constants at the top is a common pattern.

if (count < MAX_COUNT)

This reads both count (a let) and MAX_COUNT (a const). The program uses the stored values to make a decision. You will learn conditionals in Lesson 5.

6. Common Mistakes

Mistake 1 — Reassigning a const

const score = 0;
score = 10; // TypeError: Assignment to constant variable

Mistake 2 — Declaring a let twice in the same scope

let name = 'Alice';
let name = 'Bob'; // SyntaxError: Identifier 'name' has already been declared

// Use reassignment instead
let name = 'Alice';
name = 'Bob'; // Fine

Mistake 3 — Using a variable before declaring it (with let/const)

console.log(total); // ReferenceError
let total = 100;

Mistake 4 — Forgetting to declare (no keyword)

// Bad — creates an implicit global variable
count = 0;

// Good
let count = 0;

In strict mode ('use strict'), forgetting the keyword causes a ReferenceError. Always declare variables explicitly.

Mistake 5 — Poor naming

// Bad — what do these mean?
let x = 'Alice';
let y = 25;
let z = true;

// Good — self-documenting
let userName  = 'Alice';
let userAge   = 25;
let isLoggedIn = true;

7. Best Practices

  1. Prefer const by default. Switch to let only when you know the value will change.
  2. Never use var in new code.
  3. Declare variables at the top of their scope so it is easy to see what data a block works with.
  4. One variable per declaration (let x = 1; let y = 2;) — easier to read and comment.
  5. Use descriptive names. Code is read more than it is written.
  6. Use camelCase for variables and functions, UPPER_SNAKE_CASE for true constants.
  7. Initialise variables when you declare them where possible — reduces undefined-related bugs.
  8. Enable strict mode ('use strict'; at the top of your script) to catch undeclared variable errors.

8. Practice Exercise

Practice declaring and using variables.

Requirements

  1. Declare a const for your full name and log it.
  2. Declare a let for your age, log it, then reassign it to your age next year and log again.
  3. Declare a const for the tax rate (0.1) and a let for an item price (49.99). Calculate and log the total (price + tax).
  4. Declare a variable without assigning a value. Log it. Then assign a value and log it again.
  5. Try to reassign a const. What error do you see in the console?

Bonus

  • Build a "tip calculator" — declare variables for bill amount, tip percentage, and number of people. Calculate and log the tip amount and each person's share.

9. Assignment

Build a simple score tracker.

  1. Create an HTML page with: a score display, "+1 Point" button, "-1 Point" button, and a "Reset" button.
  2. In your script, declare const MIN_SCORE = 0 and const MAX_SCORE = 20.
  3. Declare let score = 0.
  4. The +1 button increases the score (but not above MAX_SCORE).
  5. The -1 button decreases the score (but not below MIN_SCORE).
  6. The Reset button sets the score back to 0.
  7. Every time the score changes, update the display on the page.
  8. When the score hits MAX_SCORE, log "Maximum score reached!" to the console.

Deliverable: A single HTML file with embedded or linked JS. Test all three buttons and confirm the score stays within bounds.

10. Interview Questions

  1. What is the difference between let, const, and var?
    let and const are block-scoped. const cannot be reassigned after declaration. var is function-scoped, can be re-declared, and is hoisted and initialised to undefined — making it error-prone. Modern JavaScript uses let and const exclusively.
  2. When would you use let vs const?
    Use const when the variable should not be reassigned (most cases). Use let when you know the value must change — loop counters, accumulators, state that is updated over time.
  3. What is variable hoisting?
    JavaScript moves variable declarations to the top of their scope before execution. var declarations are hoisted and initialised to undefined. let and const are hoisted but stay in a "temporal dead zone" — accessing them before the declaration line throws a ReferenceError.
  4. What does "block-scoped" mean?
    A block-scoped variable only exists inside the curly-brace block where it was declared. Trying to access it outside that block throws a ReferenceError. let and const are block-scoped; var is function-scoped.
  5. Can you change the value inside a const object or array?
    Yes. const prevents reassigning the variable itself, but the contents of an object or array it holds can still be modified. To prevent mutation of the contents, use Object.freeze().

11. Additional Resources

  • MDN — var, let, const — detailed reference for each keyword
  • javascript.info — Variables — excellent beginner explanation
  • MDN — Hoisting — how var hoisting works and why to avoid it
  • javascript.info — The old "var" — why var is problematic