JavaScript Variables, `let`, `const` & Data Types
📌 What This Lesson Covers
By the end of this lesson you will understand:
- What a variable is and why programs need them
- The four ways to declare variables in JavaScript and which ones to use
- The rules for naming variables (identifiers)
- The difference between
letandconst— and when to use each - What block scope means and why it matters
- What
varis and why it is no longer recommended - JavaScript’s 8 data types and how to work with each one
- How
typeoflets you check what kind of data a variable holds - The tricky behaviour of mixing strings and numbers (type coercion)
This lesson follows three phases: Understand → Practice → Build.
PHASE 1 — CONCEPTUAL UNDERSTANDING
TOPIC 1: JavaScript Variables — Containers for Data
1.1 What Is a Variable?
Imagine you are filling in a job application form. The form has labelled boxes: Name, Age, City. Each box holds one piece of information — and the label (the box name) tells you what kind of information lives there.
A variable in JavaScript works exactly the same way. It is a labelled container that holds a piece of data your program needs to use.
let name = "Amara"; // A labelled box called "name" holds the text "Amara"
let age = 25; // A labelled box called "age" holds the number 25
let city = "Lagos"; // A labelled box called "city" holds the text "Lagos"
Once you put data into a variable, you can:
- Read it (display it on the page)
- Use it in calculations
- Change it (update the value later)
- Pass it to other parts of your program
Without variables, you would have to type the same value everywhere — and if it changed, you would have to find and update every single occurrence. Variables give you one central place to store a value and one place to update it.
1.2 The Four Ways to Declare Variables in JavaScript
JavaScript gives you four ways to create a variable. Two are modern and recommended; two are older and should be avoided.
| Method | Recommended? | When Added | Notes |
|---|---|---|---|
let |
✅ Yes — modern standard | 2015 (ES6) | For values that can change |
const |
✅ Yes — modern standard | 2015 (ES6) | For values that should not change |
var |
❌ Not recommended | Original JS | Older, has confusing behaviour |
| Automatic (no keyword) | ❌ Never | Always existed | Creates global variable — dangerous |
Micro-Demo — All four styles:
let score = 100; // Modern — changeable
const PI = 3.14159; // Modern — fixed
var oldStyle = "avoid"; // Old style — not recommended
autoVar = "dangerous"; // No keyword — never do this
💡 For the rest of this course, you will use
letandconstexclusively. You will encountervarin old code online, so you need to understand it — but never use it in your own code.
1.3 Declaring and Assigning Variables
Declaring a variable means creating it — giving it a name and reserving a space in memory for it.
Assigning a value means putting something into that space.
You can do both at once:
let carName = "Toyota"; // Declare AND assign in one step
Or separately:
let carName; // Declare — the box exists but is empty
carName = "Toyota"; // Assign — put "Toyota" into the box
After declaring with no value, the variable holds the special value undefined — meaning “this box exists but nothing is in it yet.”
let carName;
console.log(carName); // Output: undefined
carName = "Toyota";
console.log(carName); // Output: Toyota
1.4 Variable Naming Rules (Identifiers — Recap + Deeper Look)
Variables must be identified with unique names. We covered the basic rules earlier; now let’s go deeper.
Core rules:
- Names can contain letters, digits, underscores (
_), and dollar signs ($) - Names must begin with a letter,
$, or_— never a number - Names are case-sensitive (
Score≠score) - Reserved keywords cannot be used (
let,const,if, etc.)
Special: Underscore (_) in variable names:
The underscore is treated as a letter. A common convention among professional developers is to start a name with _ to indicate a “private” or “internal” variable — one that is meant to be used only within a specific section of code and not from the outside.
let _lastName = "Johnson"; // conventionally "private"
let _x = 2;
let _100 = 5; // valid — underscore first, then digits
Special: Dollar Sign ($) in variable names:
The $ sign is also treated as a letter. Professional developers often use it as an alias for the main function in JavaScript libraries (for example, jQuery uses $ as its main function name):
let $ = "Hello World";
let $$$ = 2;
let $myMoney = 5;
💡 While
_and$are valid, stick to readable camelCase names for your own variables. Use_and$only when following a specific convention in the project you’re working on.
1.5 Declaring Multiple Variables at Once
You can create several variables in a single statement by separating them with commas:
let person = "John Doe", carName = "Volvo", price = 200;
Or spread across multiple lines for better readability:
let person = "John Doe",
carName = "Volvo",
price = 200;
Both are valid. The multi-line style is easier to read and easier to add comments to.
1.6 The Assignment Operator — An Important Distinction
In maths, = means “is equal to.” In JavaScript, = means “assign this value to this container.” They are completely different.
This maths statement makes no sense:
x = x + 5 ← In maths, nothing can equal itself plus 5
But in JavaScript it makes perfect sense:
let x = 10;
x = x + 5; // Read: take the current value of x (10), add 5, store the result (15) back into x
console.log(x); // Output: 15
The right side is calculated first, then the result is placed into x. The value of x has been updated from 10 to 15.
💡 The actual “is equal to” check in JavaScript is written as
==(loose equality) or===(strict equality). You will learn these operators in a later lesson.
1.7 JavaScript Arithmetic with Variables
You can perform arithmetic on number variables exactly like maths:
let x = 5 + 2 + 3; // x = 10
You can also join text strings using +:
let x = "John" + " " + "Doe"; // x = "John Doe"
⚠️ Critical warning — Mixing strings and numbers:
If you put a number inside quotes, JavaScript treats it as text. When a text string is mixed with numbers using
+, JavaScript concatenates (joins) instead of adding:
let x = "5" + 2 + 3; // Result: "523" — NOT 10!
Why? Because JavaScript reads left to right. It sees "5" (a string) and 2 (a number). Since one is text, it joins them: "52". Then it joins 3: "523". The entire result becomes text.
let x = 2 + 3 + "5"; // Result: "55"
Here, JavaScript reads left to right: 2 + 3 = 5 (number + number = number). Then 5 + "5" (number + string = string): "55".
🤔 Thinking question: What do you think
"10" - 5produces? Is it"105"or5? (Hint:-is only a maths operator — it can’t join strings. Try it in your console.)
1.8 Automatic Variables — Never Do This
JavaScript allows you to create a variable without any keyword:
x = 5; // No let, no const, no var
This works, but it creates a global variable — one that is accessible from anywhere in your entire program, which can cause unpredictable bugs in larger applications. It is considered terrible practice and should never be done.
Always declare your variables explicitly. Good practice is to declare all variables at the top of their section of code.
TOPIC 2: let — The Modern Variable Keyword
2.1 What let Does and Why It Exists
let was introduced in 2015 as part of the major JavaScript update known as ES6. It was designed to fix several confusing problems that existed with the older var keyword. let is now the standard way to declare a variable whose value can change.
let score = 0;
score = 50; // Perfectly fine — let allows updates
score = 100; // Still fine — updated again
2.2 let Cannot Be Redeclared in the Same Scope
This is one of the most important differences from var. Once you have declared a variable with let, you cannot declare it again with let in the same area of code:
let userName = "Alice";
let userName = "Bob"; // ❌ Error! Cannot redeclare 'userName'
This is actually a feature, not a bug. It prevents you from accidentally creating a second variable with the same name — a common and hard-to-find mistake in large programs.
With var, this error would not show up:
var userName = "Alice";
var userName = "Bob"; // No error — but "Alice" is now silently lost!
let protects you from this.
You can reassign (change the value) — you just cannot redeclare:
let userName = "Alice";
userName = "Bob"; // ✅ Fine — just changing the value, not redeclaring
2.3 Block Scope — The Most Important Difference Between let and var
This is one of the most important concepts in modern JavaScript.
Before understanding this, you need to know what a block is. A block is any code wrapped inside curly braces { }. Examples: the body of an if statement, the body of a for loop, the body of a function.
let has BLOCK SCOPE — a variable declared with let inside a block exists only inside that block. The moment the block ends, the variable disappears.
{
let blockVar = "I exist only inside these braces";
console.log(blockVar); // Output: I exist only inside these braces
}
console.log(blockVar); // ❌ Error! blockVar is not defined here
var has FUNCTION SCOPE (or global scope) — a variable declared with var inside a block is still accessible outside that block, as long as you are in the same function:
{
var functionVar = "I leak outside the braces";
}
console.log(functionVar); // Output: I leak outside the braces (no error!)
Why does block scope matter? A real-world example with loops:
// Using let in a for loop:
for (let i = 0; i < 3; i++) {
console.log(i); // i is available here: 0, 1, 2
}
console.log(i); // ❌ Error! i doesn't exist outside the loop
// Using var in a for loop:
for (var i = 0; i < 3; i++) {
console.log(i); // 0, 1, 2
}
console.log(i); // Output: 3 — the loop variable leaked out!
With let, your loop variable stays safely contained within the loop. With var, it leaks into the surrounding scope and can accidentally interfere with other parts of your code.
2.4 let Variables Must Be Declared Before Use (No Hoisting Surprise)
With var, there is a strange behaviour called hoisting — the browser automatically moves var declarations to the top of their scope, which means you can technically use a var variable before the line where you declared it (it will just be undefined).
let does not behave this way. If you try to use a let variable before declaring it, you get a clear error:
console.log(myVar); // Output: undefined (confusing but no error with var)
var myVar = 5;
console.log(myLet); // ❌ ReferenceError: Cannot access 'myLet' before initialization
let myLet = 5;
The let behaviour is better because it forces you to write code that reads clearly from top to bottom — the way code should be read and understood.
💡 Always declare your variables before you use them. This is good practice regardless of whether you use
letorconst.
2.5 When to Use let
Use let when the value of the variable needs to change after its first assignment. Common examples:
- A score that increases as the player earns points
- A counter that increments inside a loop
- A running total that accumulates as items are added
- A status that changes based on user input
let score = 0; // starts at zero
score = score + 10; // player earned 10 points
score = score + 5; // earned 5 more
let count = 0;
count++; // shorthand for count = count + 1
TOPIC 3: const — For Values That Should Not Change
3.1 What const Means
const stands for constant — a value that is set once and stays the same forever.
When you declare with const, two things happen:
- The variable is created and assigned a value
- JavaScript locks that assignment — it can never be changed or redeclared
const PI = 3.14159;
const COUNTRY = "Nigeria";
const TAX_RATE = 0.075;
These values will never change — PI is always PI, and the tax rate doesn’t change mid-calculation.
3.2 const Must Be Assigned When Declared
Unlike let, you cannot declare a const variable and assign it later. It must receive a value at the moment of creation:
const PI; // ❌ Error! Missing initializer in const declaration
PI = 3.14159; // This line is never reached
const PI = 3.14159; // ✅ Correct — declared and assigned together
This makes sense — if the value can never change, it must be set immediately.
3.3 const Cannot Be Reassigned
Any attempt to change a const value after it is set causes an error:
const siteName = "LearnJS";
siteName = "TechAcademy"; // ❌ TypeError: Assignment to constant variable
Expected result: An error is thrown. The assignment fails.
3.4 const Cannot Be Redeclared
Just like let, you cannot declare a const variable twice in the same scope:
const country = "Nigeria";
const country = "Ghana"; // ❌ Error: 'country' has already been declared
3.5 const Has Block Scope
const behaves exactly like let in terms of scope — it is contained within the block where it is declared:
{
const greeting = "Hello";
console.log(greeting); // Output: Hello
}
console.log(greeting); // ❌ Error! greeting is not defined outside the block
3.6 The Most Important Nuance — const with Arrays and Objects
This is one of the most commonly misunderstood concepts for beginners, and it is critical to get right.
const does NOT make the value itself unchangeable. What it makes unchangeable is the reference — the connection between the variable name and what it points to. For simple values like numbers and strings, this means the value cannot change. But for arrays and objects, the contents can still be modified.
With a const array — you CAN modify the contents:
const fruits = ["Apple", "Banana", "Mango"];
fruits.push("Orange"); // ✅ Adding an item — works fine!
fruits[0] = "Pineapple"; // ✅ Changing an item — works fine!
console.log(fruits);
// Output: ["Pineapple", "Banana", "Mango", "Orange"]
What you CANNOT do is replace the entire array:
const fruits = ["Apple", "Banana", "Mango"];
fruits = ["Kiwi", "Grape"]; // ❌ Error! Cannot reassign a const
Think of const as nailing the label to a bucket. The label cannot be moved to a different bucket. But you can still add or remove things from inside the bucket.
With a const object — same rules apply:
const car = { make: "Toyota", model: "Corolla" };
car.model = "Camry"; // ✅ Changing a property — works fine!
car.year = 2024; // ✅ Adding a new property — works fine!
car = { make: "Honda" }; // ❌ Error! Cannot reassign the entire object
3.7 When to Use const vs let — The Decision Rule
Here is the simple professional rule:
- Default to
const— always start withconst - Change to
letonly if you later need to reassign the variable’s value - Never use
varif you can useletorconst - Never use automatic variables — always use a keyword
// Good pattern:
const userName = "Alice"; // Will never change — use const
const taxRate = 0.075; // Will never change — use const
let currentScore = 0; // Will change as game progresses — use let
let itemCount = 0; // Will change as items are added — use let
3.8 Why var Is No Longer Recommended
Now that you understand let and const, here is why var causes problems:
| Problem | var behaviour |
let / const behaviour |
|---|---|---|
| Redeclaration | Allows redeclaring same name silently | Throws an error — protects you |
| Scope | Function scope — leaks out of blocks | Block scope — stays contained |
| Hoisting | Hoisted and initialised to undefined |
Hoisted but NOT initialised — throws clear error |
| Loops | Loop variable leaks outside the loop | Loop variable stays inside the loop |
The var keyword still exists in JavaScript for backward compatibility, but in new code, it should never be used. You will see it in old tutorials and legacy code — recognise it, but don’t copy it.
TOPIC 4: JavaScript Data Types
4.1 Why Data Types Exist
In the real world, different kinds of information behave differently:
- You can add numbers together:
5 + 3 = 8 - You can join text together:
"Hello" + " World" = "Hello World" - You cannot meaningfully add text to a number:
"Five" + 3 = ???
JavaScript needs to know what kind of data it is working with so it knows what operations make sense. That is what data types are for.
JavaScript has 8 data types in total. For now, you will learn the 7 most important ones in depth. The eighth (Symbol) is advanced and used in specialised scenarios.
4.2 JavaScript Is Dynamically Typed
In some languages (like Java or C), you must declare what type of data a variable will hold, and it cannot change:
int score = 100; // Java — this variable can ONLY ever hold integers
JavaScript works differently. The same variable can hold any type of data, and the type can even change:
let x = 10; // x holds a number
x = "Hello"; // x now holds a string — JavaScript allows this
x = true; // x now holds a boolean — still allowed
This is called dynamic typing. It makes JavaScript flexible, but it also means you need to be careful about what type of data you expect a variable to hold.
4.3 Data Type 1 — String
A string is any piece of text. It is written inside single quotes, double quotes, or backticks (template literals, which you will learn later).
let name = "Alice"; // double quotes
let city = 'Lagos'; // single quotes
let message = `Hello, World!`; // backticks (template literal)
All three produce a string. The choice of quote style is yours — just be consistent and match the opening and closing type.
Important: If you put a number inside quotes, it becomes a string — not a number:
let price = "100"; // This is the STRING "100", not the NUMBER 100
You cannot do maths with it — it will concatenate instead.
4.4 Data Type 2 — Number
JavaScript has only one number type for all numeric values — whether whole numbers or decimals. Unlike most programming languages that distinguish between integers and floating-point numbers, JavaScript uses a single flexible number type:
let age = 28; // whole number (integer)
let price = 19.99; // decimal number (float)
let temperature = -5; // negative number
let big = 1e6; // scientific notation: 1,000,000
Special number values:
let infinity = Infinity; // represents mathematical infinity
let negInfinity = -Infinity;
let notANumber = NaN; // "Not a Number" — result of invalid maths
NaN appears when you try to do maths with something that isn’t a valid number:
let result = 100 / "apple"; // Can't divide by text
console.log(result); // Output: NaN
4.5 Data Type 3 — BigInt
A standard JavaScript number can safely represent integers up to about 9 quadrillion (9,007,199,254,740,991). Beyond that, precision is lost.
BigInt was introduced to handle numbers larger than this limit. You create a BigInt by adding the letter n to the end of a number:
let hugeNumber = 9007199254740991n; // BigInt
let result = hugeNumber + 1n; // Must use n on both sides
console.log(result); // Output: 9007199254740992n
Real-world use: BigInt is used in cryptography, financial systems handling very large transaction IDs, and scientific computing. For everyday JavaScript programming, regular numbers are sufficient.
4.6 Data Type 4 — Boolean
A boolean is the simplest data type — it can only ever be one of two values: true or false.
Think of it like a light switch: it is either ON or OFF. There is no in-between.
let isLoggedIn = true;
let hasPermission = false;
let isOver18 = true;
Booleans are used constantly in programming to make decisions:
- Is the user logged in? (
true/false) - Has the form been filled correctly? (
true/false) - Is the item in stock? (
true/false)
let temperature = 35;
let isHot = temperature > 30; // Evaluates to: true
console.log(isHot); // Output: true
⚠️ Beginner Mistake:
trueandfalseare written in lowercase with no quotes."true"(with quotes) is a string — a completely different thing!
4.7 Data Type 5 — Undefined
undefined is the value a variable holds when it has been declared but not yet assigned a value. JavaScript automatically gives this value to empty variables.
let score;
console.log(score); // Output: undefined
console.log(typeof score); // Output: "undefined"
After assigning:
score = 100;
console.log(score); // Output: 100
Real-world analogy: Think of a form field that exists on the page (the variable is declared) but the user hasn’t filled it in yet (no value assigned). It is a valid field — it just doesn’t have a value yet.
4.8 Data Type 6 — Null
null means “intentionally empty” — the variable exists, but you have deliberately set it to have no value. It is not undefined (which means “not yet assigned”); it means “I am choosing to leave this empty.”
let selectedUser = null; // No user selected yet — by choice
Later, when a user is selected:
selectedUser = { name: "Alice", id: 42 };
The difference between null and undefined:
undefined: the variable exists but was never given a valuenull: the developer explicitly chose to make the variable empty
let a; // undefined — not yet assigned
let b = null; // null — deliberately set to empty
💡
typeof nullreturns"object"— this is a well-known quirk in JavaScript that has existed since the language was first created. It is considered a bug in the language, but it cannot be fixed now without breaking millions of existing websites.
4.9 Data Type 7 — Object
An object is a complex data type that groups related information together. Where a simple variable holds one value, an object can hold many values — each one given a name (called a property).
Think of an object like a profile card: it describes one thing from multiple angles.
const student = {
name: "James",
age: 20,
course: "Computer Science",
isEnrolled: true
};
console.log(student.name); // Output: James
console.log(student.age); // Output: 20
The object data type in JavaScript also includes arrays and dates:
// Array — a list of values
const colours = ["red", "green", "blue"];
// Date — a date/time object
const today = new Date();
You will study objects, arrays, and dates in dedicated lessons later. For now, understand that the object type is JavaScript’s way of storing structured, multi-property data.
4.10 The typeof Operator — Checking a Variable’s Data Type
typeof is a built-in operator that tells you what data type a value or variable currently holds. It returns a string describing the type.
typeof "Alice" // Returns: "string"
typeof 42 // Returns: "number"
typeof 3.14 // Returns: "number"
typeof true // Returns: "boolean"
typeof undefined // Returns: "undefined"
typeof null // Returns: "object" ← famous quirk!
typeof { name: "Alice" } // Returns: "object"
typeof [1, 2, 3] // Returns: "object" ← arrays are objects in JS
typeof function(){} // Returns: "function"
Practical use — checking a variable’s type before using it:
let userInput = "25"; // came from a form — might be a string
console.log(typeof userInput); // Output: "string"
// If we need a number for calculations, we need to convert it
4.11 Summary Table — All 8 Data Types
| Data Type | What It Holds | Example |
|---|---|---|
| String | Text | "Hello", 'World' |
| Number | Any numeric value | 42, 3.14, -7 |
| BigInt | Very large integers | 9007199254740991n |
| Boolean | True or false only | true, false |
| Undefined | Declared but not assigned | let x; |
| Null | Intentionally empty | let y = null; |
| Symbol | Unique identifier (advanced) | Symbol("id") |
| Object | Structured data / collections | {name: "Alice"}, [1,2,3] |
PHASE 2 — APPLIED EXERCISES
Exercise 1 — Variables in the Real World
Objective: Declare variables correctly using let and const, and understand the difference through a practical scenario.
Scenario: You are building a simple product page for an online shop. Some information about the product never changes (name, price, category). Other information changes during the shopping session (quantity selected, total cost).
Warm-Up Mini-Example:
const itemName = "Notebook"; // Fixed — const
let quantityInCart = 0; // Changes — let
quantityInCart = quantityInCart + 2;
console.log(quantityInCart); // Output: 2
Your Exercise:
Step 1 — Create shop.html:
<!DOCTYPE html>
<html>
<body>
<h2>Product Page</h2>
<p id="productInfo"></p>
<p id="cartInfo"></p>
<p id="totalInfo"></p>
<script src="shop.js"></script>
</body>
</html>
Step 2 — Create shop.js:
// Product details — fixed values, use const
const productName = "Wireless Headphones";
const productPrice = 12500; // price in Naira
const productCategory = "Electronics";
const productBrand = "SoundWave";
// Shopping session — values that change, use let
let quantitySelected = 0;
let totalCost = 0;
// Simulate a customer adding 3 items to cart
quantitySelected = 3;
totalCost = productPrice * quantitySelected;
// Display product information
document.getElementById("productInfo").innerHTML =
productBrand + " " + productName + " | Category: " + productCategory + " | Price: ₦" + productPrice;
// Display cart information
document.getElementById("cartInfo").innerHTML =
"Quantity in cart: " + quantitySelected;
// Display total
document.getElementById("totalInfo").innerHTML =
"Total: ₦" + totalCost;
// Developer check
console.log("Product:", productName);
console.log("Quantity:", quantitySelected);
console.log("Total cost:", totalCost);
Expected page output:
SoundWave Wireless Headphones | Category: Electronics | Price: ₦12500
Quantity in cart: 3
Total: ₦37500
Expected console output:
Product: Wireless Headphones
Quantity: 3
Total cost: 37500
Step 3 — Test const protection: Try adding this line to your code:
productPrice = 10000; // Try to change the price
Observe: An error appears in the console because const prevents reassignment.
Self-Check Questions:
- Why did you use
constforproductNameandproductPrice? - Why did you use
letforquantitySelectedandtotalCost? - What value did
quantitySelectedhold immediately afterlet quantitySelected = 0;before you set it to 3? - What would happen if you tried to declare
const productName = "Earbuds";again in the same script?
Optional What-If Challenge: Add a discount of 500 Naira per item if the customer buys 3 or more. Update the total calculation.
Exercise 2 — Block Scope in Action
Objective: See the difference between let (block-scoped) and var (function-scoped) through hands-on experimentation.
Scenario: You are writing a temperature converter that needs a temporary variable inside a calculation block.
Warm-Up Mini-Example:
{
let insideBlock = "I only exist in here";
console.log(insideBlock); // Works: "I only exist in here"
}
// console.log(insideBlock); // Would crash — try uncommenting to see the error
Your Exercise:
Step 1 — Create this file and run it, reading each console.log carefully:
// Scenario: temperature conversion inside a block
let outsideTemp = 100; // Celsius, declared outside
{
// Conversion block — Celsius to Fahrenheit
let fahrenheit = (outsideTemp * 9 / 5) + 32; // block-scoped variable
console.log("Inside block — fahrenheit:", fahrenheit); // Works
console.log("Inside block — outsideTemp:", outsideTemp); // Works (can reach outside)
}
console.log("Outside block — outsideTemp:", outsideTemp); // Works
// console.log("Outside block — fahrenheit:", fahrenheit); // Would crash!
Expected console output:
Inside block — fahrenheit: 212
Inside block — outsideTemp: 100
Outside block — outsideTemp: 100
Step 2 — Now repeat the experiment replacing let fahrenheit with var fahrenheit. Uncomment the last console.log. Observe the difference.
Self-Check Questions:
- Why could the block access
outsideTemp? (Hint: scope looks outward, not inward) - Why did
fahrenheitcause an error outside the block when declared withlet? - What was different when you used
var? Is that better or worse? Why? - Can you think of a real situation where a variable should only exist temporarily inside a calculation block?
Exercise 3 — Data Types Explorer
Objective: Work with all the main data types and use typeof to verify what type each variable holds.
Scenario: You are building the backend of a user registration system. Each piece of information has a specific type, and the system must verify what type it is dealing with before processing it.
Warm-Up Mini-Example:
let userName = "Alice";
console.log(typeof userName); // Output: "string"
let userAge = 30;
console.log(typeof userAge); // Output: "number"
Your Exercise:
// User registration data — different types
const firstName = "Chukwudi"; // String
const lastName = "Okonkwo"; // String
const age = 22; // Number
const gpa = 3.75; // Number (decimal)
const isEnrolled = true; // Boolean
let graduationYear; // Undefined — not assigned yet
const profilePicture = null; // Null — no picture uploaded yet
// Display each value and its type in the console
console.log("First Name:", firstName, "| Type:", typeof firstName);
console.log("Last Name:", lastName, "| Type:", typeof lastName);
console.log("Age:", age, "| Type:", typeof age);
console.log("GPA:", gpa, "| Type:", typeof gpa);
console.log("Is Enrolled:", isEnrolled, "| Type:", typeof isEnrolled);
console.log("Graduation Year:", graduationYear, "| Type:", typeof graduationYear);
console.log("Profile Picture:", profilePicture, "| Type:", typeof profilePicture);
Expected console output:
First Name: Chukwudi | Type: string
Last Name: Okonkwo | Type: string
Age: 22 | Type: number
GPA: 3.75 | Type: number
Is Enrolled: true | Type: boolean
Graduation Year: undefined | Type: undefined
Profile Picture: null | Type: object
🤔 Thinking question: The last line shows
typeof nullreturns"object". Does that meannullis actually an object? No — this is a historical bug in JavaScript.nullmeans “intentionally empty,” not “an object.” This is why you should usenull === nullto check for null, nottypeof x === "object".
Step 2 — Add this to test the string + number mixing behaviour:
// Type coercion experiments
let result1 = "5" + 2 + 3;
let result2 = 2 + 3 + "5";
let result3 = "10" - 5; // Subtraction can't concatenate!
console.log("'5' + 2 + 3 =", result1, "| Type:", typeof result1);
console.log("2 + 3 + '5' =", result2, "| Type:", typeof result2);
console.log("'10' - 5 =", result3, "| Type:", typeof result3);
Expected output:
'5' + 2 + 3 = 523 | Type: string
2 + 3 + '5' = 55 | Type: string
'10' - 5 = 5 | Type: number
Self-Check Questions:
- Why does
typeof nullreturn"object"even thoughnullis not an object? - What is the difference between
undefinedandnullin practical terms? - Why did
"10" - 5produce the number5, while"5" + 2produced the string"52"? - If a form sends you a user’s age as
"25"(a string from a text field), how would that cause problems in an age verification calculation?
PHASE 3 — PROJECT SIMULATION
Mini-Project: Smart Student Tracker
Project Overview: You will build a student information tracker that correctly uses const and let, works with multiple data types, and displays meaningful information on a webpage. This is the kind of data management task common in school administration systems, HR dashboards, and CRM tools.
Stage 1 — Declaring and Displaying Student Data
Goal: Set up all variables with the correct keywords and display the student profile.
Illustrative Preview:
const studentId = "STU-001";
let totalMarks = 0;
console.log(typeof studentId); // "string"
console.log(typeof totalMarks); // "number"
Build tracker.html:
<!DOCTYPE html>
<html>
<head>
<title>Student Tracker</title>
</head>
<body>
<h1>🎓 Student Tracker</h1>
<hr>
<p id="profile"></p>
<p id="status"></p>
<p id="academics"></p>
<p id="types"></p>
<p id="summary"></p>
<script src="tracker.js"></script>
</body>
</html>
Build tracker.js — Stage 1:
/*
File: tracker.js
Project: Smart Student Tracker — Stage 1
Purpose: Declare and display student data with correct variable types
*/
// Fixed student identity — use const
const studentId = "STU-2025-007";
const fullName = "Ngozi Adeleke";
const programme = "Business Administration";
const enrollmentYear = 2023;
// Dynamic student data — use let
let currentLevel = 200; // can change each year
let isCurrentlyEnrolled = true; // can change if student defers
let outstandingFees = null; // null = no fees outstanding yet
// Academic scores — use let (will be updated)
let mathScore = 0;
let englishScore = 0;
let economicsScore = 0;
// Display profile
document.getElementById("profile").innerHTML =
"ID: " + studentId +
" | Name: " + fullName +
" | Programme: " + programme +
" | Enrolled: " + enrollmentYear;
// Display status
document.getElementById("status").innerHTML =
"Current Level: " + currentLevel +
"L | Enrolled: " + isCurrentlyEnrolled +
" | Outstanding Fees: " + outstandingFees;
// Show data types
document.getElementById("types").innerHTML =
"Types → studentId: " + typeof studentId +
" | currentLevel: " + typeof currentLevel +
" | isCurrentlyEnrolled: " + typeof isCurrentlyEnrolled +
" | outstandingFees: " + typeof outstandingFees;
console.log("Tracker loaded for:", fullName);
Expected page output:
ID: STU-2025-007 | Name: Ngozi Adeleke | Programme: Business Administration | Enrolled: 2023
Current Level: 200L | Enrolled: true | Outstanding Fees: null
Types → studentId: string | currentLevel: number | isCurrentlyEnrolled: boolean | outstandingFees: object
Stage 2 — Updating Values and Performing Calculations
Goal: Update let variables as the student’s situation changes, and perform academic calculations.
Illustrative Preview:
let score = 0;
score = 78; // update
let grade = score >= 70 ? "A" : "B"; // expression
console.log(grade); // Output: A
Add to tracker.js:
// Assign actual scores for this semester
mathScore = 78;
englishScore = 85;
economicsScore = 69;
// Calculations
let totalScore = mathScore + englishScore + economicsScore;
let averageScore = totalScore / 3;
let maxPossible = 300;
let percentage = (totalScore / maxPossible) * 100;
// Determine class of degree based on average
let classification;
if (averageScore >= 70) {
classification = "First Class";
} else if (averageScore >= 60) {
classification = "Second Class Upper";
} else if (averageScore >= 50) {
classification = "Second Class Lower";
} else {
classification = "Third Class";
}
// Simulate level change — student moved to 300 level
currentLevel = 300;
// Simulate fees update
outstandingFees = 45000; // fees outstanding — null changed to a number
// Display academic results
document.getElementById("academics").innerHTML =
"Math: " + mathScore + " | English: " + englishScore + " | Economics: " + economicsScore +
" | Total: " + totalScore + "/300 | Average: " + averageScore.toFixed(1) + "%" +
" | Classification: " + classification;
// Update status display
document.getElementById("status").innerHTML =
"Current Level: " + currentLevel +
"L | Enrolled: " + isCurrentlyEnrolled +
" | Outstanding Fees: ₦" + outstandingFees;
console.log("Updated level:", currentLevel);
console.log("Classification:", classification);
console.log("typeof outstandingFees after update:", typeof outstandingFees);
Expected updated page output (academics line):
Math: 78 | English: 85 | Economics: 69 | Total: 232/300 | Average: 77.3% | Classification: First Class
Expected console output:
Updated level: 300
Classification: First Class
typeof outstandingFees after update: number
Stage 3 — Final Summary and Type Safety Check
Goal: Display a complete summary and add a type-safety demonstration that mirrors what real applications do before processing data.
Add to tracker.js:
// Type safety check — simulating data validation
let incomingScoreFromForm = "92"; // Score came from a form — it's a string!
console.log("Incoming score type:", typeof incomingScoreFromForm); // "string"
console.log("Incorrect sum:", mathScore + incomingScoreFromForm); // "7892" — wrong!
// Convert to number for correct calculation
let correctedScore = Number(incomingScoreFromForm);
console.log("Corrected score type:", typeof correctedScore); // "number"
console.log("Correct sum:", mathScore + correctedScore); // 170 — correct!
// Final summary display
document.getElementById("summary").innerHTML =
"SEMESTER SUMMARY — " + fullName +
" | ID: " + studentId +
" | Level: " + currentLevel + "L" +
" | Classification: " + classification +
" | Outstanding: ₦" + outstandingFees;
console.log("=== FINAL REPORT ===");
console.log("Student:", fullName);
console.log("ID:", studentId);
console.log("Average:", averageScore.toFixed(1) + "%");
console.log("Classification:", classification);
Expected console output (new lines):
Incoming score type: string
Incorrect sum: 7892
Corrected score type: number
Correct sum: 170
=== FINAL REPORT ===
Student: Ngozi Adeleke
ID: STU-2025-007
Average: 77.3%
Classification: First Class
Reflection Questions:
-
You used
constforstudentId,fullName, andprogramme. Why would it be dangerous if these values could be accidentally changed mid-program? -
outstandingFeesstarted asnulland was later updated to45000. What didtypeof outstandingFeesreturn when it wasnull? Did the type change when it became45000? What does this tell you about dynamic typing? -
The incoming score from the form was
"92"(a string). Adding it tomathScoregave"7892"instead of170. In a real school system, what kind of mistakes could this cause? -
Look at the
constvariables in your code. Could any of them logically benefit from beinglet? Could any of theletvariables safely beconst? -
If this tracker were a real system used by a university, what other data types would you expect to store? What would be
const, what would belet, and why?
Optional Advanced Features:
- Add a
constarray calledsubjectsthat holds the subject names, and display them on the page - Add a second student and compare their averages — display who has the higher score
- Use
typeofto build a simple “data validator” that checks each variable’s type before displaying it - Add a boolean
hasScholarshipand calculate a discounted fee iftrue
✅ COMPLETION CHECKLIST
| Item | Status |
|---|---|
| Variables explained as labelled data containers | ✅ |
All four declaration methods covered (let, const, var, automatic) |
✅ |
Identifier naming rules explained with _ and $ covered |
✅ |
| Multiple variable declaration in one statement shown | ✅ |
Assignment operator (=) vs equality (==) distinction explained |
✅ |
| String + number mixing and type coercion explained | ✅ |
let — redeclaration protection explained with examples |
✅ |
let — block scope vs var function scope explained with loops |
✅ |
let — hoisting behaviour explained and compared to var |
✅ |
const — must be assigned at declaration |
✅ |
const — cannot be reassigned or redeclared |
✅ |
const — arrays and objects: contents can change, reference cannot |
✅ |
Decision rule for const vs let clearly stated |
✅ |
Why var is no longer recommended — full comparison table |
✅ |
| All 8 data types explained with examples | ✅ |
| Dynamic typing explained and illustrated | ✅ |
typeof operator explained and demonstrated |
✅ |
null vs undefined distinction explained |
✅ |
typeof null quirk explained |
✅ |
| Three applied exercises with warm-ups, hints, and self-checks | ✅ |
| Real-world mini-project built across three stages | ✅ |
| Reflection questions included | ✅ |
| Every concept includes at least one example with expected output | ✅ |
One-sentence summary: Variables are named data containers declared with const (for fixed values) or let (for changeable values), and understanding JavaScript’s eight data types — along with how typeof reveals them — is the foundation for writing safe, predictable programs.