⚡ Phase 1 · Foundations 🟢 Beginner MODULE 02

Variables & Data Types

⏱️ 30 min read
📖 Theory + Code
🧩 5 Quiz Questions
🏗️ 1 Challenge
Your progress in Phase 114%
🎯 What you'll learn: How to store data with variables using var, let, and const, JavaScript's 7 primitive data types, how typeof works, the quirky world of type coercion, and why null !== undefined.

What is a Variable?

A variable is a named container that stores a value in memory. Think of it like a labeled box — you put something inside and refer to it later by the label. Variables are the most fundamental building block in any programming language.

In JavaScript, you declare a variable using one of three keywords: var, let, or const. Each behaves differently — and choosing the right one matters.

Modern JS uses let and const
var is the old way and has confusing, bug-prone behavior. Modern JavaScript (ES6+) replaced it with let and const. In this course, we always use let and const — you'll understand why after this lesson.
variables-intro.js
JAVASCRIPT
// Three ways to declare variables in JavaScript
var   oldName = "Alice";  // Old — avoid
let   score   = 100;      // Modern — use for reassignable values
const PI      = 3.14159; // Modern — use for constants (can't change)

console.log(oldName); // "Alice"
console.log(score);   // 100
console.log(PI);      // 3.14159

var, let, and const

var (Old — Avoid)

var is function-scoped, which means it ignores block boundaries like if statements and loops. It can also be redeclared, and it gets "hoisted" — moved to the top of its scope automatically, which causes surprising behavior.

var-problems.js — Why var causes bugs
JAVASCRIPT
var name = "Alice";
var name = "Bob"; // No error! Silently redeclared
console.log(name); // "Bob"

var x = 1;
if (true) {
  var x = 2; // Same variable! var ignores block scope
}
console.log(x); // 2  (surprising! expected 1)
⚠️
var is function-scoped — causes confusing bugs
Because var doesn't respect block scope, a variable declared inside an if block leaks out to the surrounding function. This causes hard-to-find bugs. Modern code should always use let and const instead.

let (Modern — Use This)

let is block-scoped — it lives only inside the {} where it was declared. It can be reassigned but not redeclared. Use let when you know the value will change over time.

let-examples.js
JAVASCRIPT
let score = 0;
score = 10; // OK: reassignment is allowed
score = 25; // OK: reassignment again
// let score = 20; // ERROR: can't redeclare with let

if (true) {
  let inner = "only inside this block";
  console.log(inner); // works fine here
}
// console.log(inner); // ERROR: inner is not defined outside the block

console.log(score); // 25 — still accessible here

const (Constant — Use When Value Won't Change)

const is also block-scoped like let, but it cannot be reassigned after declaration. Use const by default — only switch to let when you know you need to reassign.

const-examples.js
JAVASCRIPT
const MAX_SCORE = 100;
// MAX_SCORE = 200; // ERROR: Assignment to constant variable

const userName = "Ahmed";
// userName = "Sara"; // ERROR: can't reassign const

// IMPORTANT: const with objects/arrays — the reference is constant,
// but the contents can still be mutated!
const user = { name: "Ahmed", age: 25 };
user.age = 26;  // OK! Mutating the object's property
console.log(user.age); // 26

const colors = ["red", "blue"];
colors.push("green"); // OK! Mutating the array
console.log(colors);   // ["red", "blue", "green"]

When to Use Which?

Keyword Scope Reassignable Redeclarable Recommendation
const Block No No Use by default
let Block Yes No When value changes
var Function Yes Yes Avoid — legacy

The 7 Primitive Data Types

JavaScript has 7 primitive data types. These are the building blocks of all data — every value you work with is either one of these primitives, or an object built from them.

📝
string
"hello", 'world', `template` — text data
🔢
number
42, 3.14, -7, Infinity, NaN — all numbers
boolean
true or false — logical values
null
Intentional absence of value — you set it
undefined
Variable declared but not yet assigned
🔑
symbol
Unique identifier — ES6+, advanced use
🔭
bigint
Integers beyond Number.MAX_SAFE_INTEGER
all-types.js — All 7 primitive types
JAVASCRIPT
// 1. string — text in quotes
const name       = "Ahmed";
const greeting   = 'Hello, World!';
const template   = `My name is ${name}`; // template literal

// 2. number — integers and floats (same type in JS!)
const age        = 25;
const price      = 9.99;
const negative   = -42;
const infinite   = Infinity;
const notANumber = NaN;   // result of invalid math

// 3. boolean — true or false only
const isLoggedIn = true;
const hasError   = false;

// 4. null — intentional "no value"
const selectedUser = null;

// 5. undefined — declared but not assigned
let futureValue;
console.log(futureValue); // undefined

// 6. symbol — unique identifier (advanced)
const id1 = Symbol("id");
const id2 = Symbol("id");
console.log(id1 === id2); // false — always unique!

// 7. bigint — huge integers with n suffix
const bigNumber = 9007199254740991n;
console.log(typeof bigNumber); // "bigint"

The typeof Operator

The typeof operator returns a string describing the type of any value. It's extremely useful for debugging and type-checking in JavaScript.

typeof-examples.js
JAVASCRIPT
console.log(typeof "hello");     // "string"
console.log(typeof 42);          // "number"
console.log(typeof 3.14);        // "number" (floats are numbers too!)
console.log(typeof true);        // "boolean"
console.log(typeof undefined);  // "undefined"
console.log(typeof Symbol());    // "symbol"
console.log(typeof 9007n);       // "bigint"

// THE FAMOUS JAVASCRIPT BUG:
console.log(typeof null);        // "object" ← this is WRONG but unfixable
console.log(typeof {});           // "object"
console.log(typeof []);           // "object" (arrays are also objects)
console.log(typeof function(){}); // "function"
⚠️
typeof null returns "object" — a famous JS bug!
typeof null === "object" is a well-known JavaScript bug from 1995. Brendan Eich has acknowledged it as a mistake, but it can never be fixed because millions of programs depend on this buggy behavior. Always check for null explicitly: if (value === null).

Type Coercion — JS's Quirky Behavior

JavaScript automatically converts types when you mix them in operations — this is called implicit type coercion. It's one of the most confusing aspects of JavaScript for beginners, but once you understand it, you can avoid its traps.

⚠️
Type coercion is one of the trickiest parts of JS
JavaScript tries to be "helpful" by automatically converting types. Sometimes that's convenient, but it often leads to bugs that are very hard to track down. Understanding the rules is essential.
type-coercion.js — The weird world of JS types
JAVASCRIPT
// ── String + Number = String concatenation! ──────
"5" + 3       // "53"  (NOT 8 — string wins with +)
"5" + 3 + 2   // "532" (left to right)
3 + 2 + "5"   // "55"  (3+2=5 first, then "5"+"5"="55")

// ── Subtraction converts to number ───────────────
"5" - 3       // 2  (- always converts to number)
"10" * 2      // 20
"10" / 2      // 5
"abc" - 1     // NaN (can't convert "abc" to number)

// ── Boolean coercion ─────────────────────────────
true  + 1     // 2  (true = 1)
false + 1     // 1  (false = 0)
true  + true  // 2

// ── Comparison: loose vs strict ──────────────────
"5" ==  5     // true  (loose == coerces types)
"5" === 5     // false (strict === no coercion)
0   ==  false // true  (0 is falsy)
0   === false // false (different types)
""  ==  false // true  (empty string is falsy)
Always use === (strict equality)
Using === instead of == prevents type coercion surprises. This is one of the most important JavaScript best practices. === checks both value AND type. The only time to use == is when you explicitly want type coercion — which is rare.

null vs undefined

Both null and undefined represent "no value" — but they have very different meanings and origins. Knowing the difference prevents common bugs.

null-vs-undefined.js
JAVASCRIPT
// undefined — JS says "no value was given"
let username; // declared but not assigned
console.log(username); // undefined

function greet(name) {
  console.log(name); // undefined if no arg passed
}
greet(); // undefined

// null — YOU intentionally say "no value"
let loggedInUser = null; // no one is logged in yet
console.log(loggedInUser); // null

// Later, when someone logs in:
loggedInUser = { name: "Ahmed", role: "admin" };

// Comparing null and undefined
console.log(null ==  undefined); // true  (loose — both are "empty")
console.log(null === undefined); // false (strict — different types)
💡
The empty box analogy
null is an empty box that you deliberately emptied — you chose to put "nothing" in it.
undefined is a box that was never filled in the first place — it was declared but JS never received a value for it.

Dynamic Typing

JavaScript is dynamically typed — a variable can hold any type, and you can change its type at any time. You don't need to declare what type a variable is; JavaScript figures it out at runtime.

dynamic-typing.js
JAVASCRIPT
// JavaScript: same variable, different types — all valid
let x = 42;
console.log(typeof x); // "number"

x = "hello";
console.log(typeof x); // "string"

x = true;
console.log(typeof x); // "boolean"

x = { name: "Ahmed" };
console.log(typeof x); // "object"

// In Java/C++, this would be a compile error:
// int x = 42;  x = "hello";  // ERROR in Java

// In Python, dynamic typing works similarly:
// x = 42; x = "hello"  # Python also allows this
Consider TypeScript for large projects
Dynamic typing is flexible but can cause bugs in large codebases when you lose track of what type a variable holds. TypeScript is a superset of JavaScript that adds optional static types. Many large companies (Google, Microsoft, Airbnb) use TypeScript for this reason. We'll cover it in an advanced course!

Variable Naming Rules

JavaScript has strict rules about what you can name a variable, plus widely adopted conventions. Breaking the rules causes errors; ignoring conventions makes your code hard to read.

naming-rules.js
JAVASCRIPT
// ✅ VALID names — can start with letter, $, or _
let userName = "Ahmed";     // camelCase (JS standard)
let _private = true;        // underscore prefix convention
let $element = null;        // dollar sign (used by jQuery)
const MAX_SIZE = 100;       // UPPER_CASE for constants
class UserProfile {}       // PascalCase for classes

// ❌ INVALID names — will throw SyntaxError
// let 1name = "bad";        // can't start with a number
// let user-name = "bad";    // hyphen is minus operator
// let user name = "bad";    // no spaces allowed
// let class = "bad";        // reserved keyword

// 🚫 JS reserved keywords (can't use as names):
// var, let, const, if, else, for, while, function,
// return, class, new, this, typeof, delete, in, of...

// 👍 Good descriptive names
let isUserLoggedIn = true;  // boolean: use is/has/can prefix
let totalScore = 0;
let firstName = "Ahmed";

// 👎 Bad names — avoid these
let a = true;               // meaningless
let x1 = "Ahmed";          // what is x1?
let temp = 9.99;            // temp what?

Lesson Summary

Let's recap the key concepts from this lesson:

A variable is a named container that stores a value. Use const by default, let when you need to reassign, never use var.
const and let are both block-scoped. var is function-scoped and causes confusing bugs — avoid it.
JavaScript has 7 primitive types: string, number, boolean, null, undefined, symbol, bigint.
typeof returns a string of the type. Important bug: typeof null === "object" — always check null explicitly.
Type coercion: JS auto-converts types. "5" + 3 = "53" but "5" - 3 = 2. Always use === not ==.
null = you intentionally set "no value". undefined = JS never received a value. Both are "empty" but different.
JavaScript is dynamically typed — variables can change type. Use camelCase for variable names.
🧩 Knowledge Check — Lesson 2
Answer all 5 questions to test your understanding. Instant feedback on every answer.
1. Which keyword creates a block-scoped variable that CAN be reassigned?
2. What does typeof null return in JavaScript?
3. What is the result of "5" + 3 in JavaScript?
4. What is the difference between null and undefined?
5. Which of these is the correct JS naming convention for variables?
💪
Coding Challenge — Lesson 2
Apply what you learned · Beginner Level

Now it's your turn. Apply everything from this lesson in one practical program.

Challenge: Build a Student Profile 🎓

Create a JavaScript file called student.js. Declare variables to represent a complete student profile:
  • const — Student's full name
  • let — Age (a number)
  • let — GPA (a decimal number)
  • const — isEnrolled (boolean — true)
  • let — favoriteSubject (a string)
  • const — studentId (null initially — explain why in a comment)
Then log each variable with a descriptive label:
console.log("Name:", name); Finally, try reassigning the age after one year and log it again.
💡 Show hints if you're stuck
  • Use const for things that don't change (name, enrollment status)
  • Use let for things that can change (age, GPA, favoriteSubject)
  • null means "not yet assigned" — the student ID hasn't been issued yet
  • typeof works on any variable: console.log(typeof age)
  • Try to reassign the const name — you'll see an error! That's expected.
Finished this lesson?
Mark it complete to track your progress.
🎉

Lesson 2 Complete!

You now understand JavaScript's variable system and all 7 primitive types. You're building real foundational knowledge — keep it up!

Module 02 of 15 Phase 1 — JS Foundations