SECTION 1
Historical Context & Motivation
Every programming language needs a way to represent different kinds of information — a person's name, their age, whether they are logged in — and JavaScript is no exception. When Brendan Eich created JavaScript in just ten days in 1995, he made a deliberate choice: the language would be dynamically typed, meaning a variable does not have to declare what kind of data it holds. This made the language approachable for beginners, but it also introduced surprises that even experienced developers still encounter today. Understanding data types is the first step toward writing predictable code.
1995 • JavaScript Is Born
1997 • ECMAScript 1 Standard
typeof operator reports them.2009 • ES5 and Strict Mode
2015 • ES6 Adds Symbol & More
let and const for block-scoped variables, plus the new Symbol type. The original five types remain the core building blocks.2020 • BigInt Arrives
Despite decades of evolution, the five original primitive types — number, string, boolean, null, and undefined — remain the most important to learn first. The central question this lesson addresses is: What kind of data am I working with, and how does that data type change the behavior of my expressions?
SECTION 2
Core Principles & Definitions
A data type tells the JavaScript engine what kind of value a piece of data is — and therefore what operations make sense for it. You can add two numbers, but "adding" two booleans has a very different meaning. JavaScript groups its types into two families: primitives (simple, immutable values) and objects (complex, mutable structures). This lesson focuses on the five primitive types you will use every day.
Number
42, 3.14, -7, and the special values NaN and Infinity.String
"hello", 'world', or backtick template literals like `Hi, ${name}`. Strings are immutable — once created, individual characters cannot be changed in place.Boolean
true or false. Booleans drive every if statement and loop condition. Comparison operators like === and > always produce a boolean.Null
null to signal that it is intentionally empty. Note: typeof null returns "object" — a famous bug from 1995 that was never fixed.Undefined
KEY TAKEAWAY
SECTION 3
Visual Explanation — The Type Landscape
typeof operator. Notice the ⚠ warning on null — it incorrectly reports as "object" due to a legacy bug.The diagram above lays out the five primitive types you will encounter in nearly every JavaScript program. The typeof operator is your go-to tool for inspecting what type a value is at runtime. You can use it like this: typeof 42 returns "number", and typeof "hello" returns "string". This is incredibly useful for debugging when your code does something unexpected.
SECTION 4
How Types Affect Expressions
In JavaScript, the + operator behaves differently depending on the types involved. When both operands are numbers, JavaScript performs arithmetic addition. But when at least one operand is a string, JavaScript performs string concatenation — it glues the two values together as text. This behavior is called type coercion, and it is one of the most common sources of bugs for beginners.
ADDITION (NUMBERS)
When the + operator receives two number values, it adds them normally.
CONCATENATION (STRING + NUMBER)
When at least one operand is a string, JavaScript converts the other to a string and joins them. The number 3 becomes "3" and the result is the string "53".
SUBTRACTION FORCES NUMBERS
Unlike +, the − operator has no string meaning, so JavaScript converts "10" to the number 10 before subtracting.
BOOLEAN COERCION IN ARITHMETIC
When booleans appear in arithmetic, true becomes 1 and false becomes 0. So true + true evaluates to 2.
Why This Matters
"17" (a string), not 17 (a number). If you write age + 1, you get "171" instead of 18. Converting with Number(age) + 1 fixes the problem.SECTION 5
Detailed Breakdown — Type Coercion & Truthiness
JavaScript does not just coerce types during arithmetic. Whenever you use a value in a boolean context — such as an if statement — the engine converts that value to true or false. Values that convert to false are called falsy, and everything else is truthy. There are exactly six falsy primitive values, and knowing them will save you from a lot of debugging.
"0" is truthy even though the number 0 is falsy.| Expression | Result | Why |
|---|---|---|
Boolean(0) | false | Zero is one of the six falsy values. |
Boolean("") | false | An empty string is falsy. |
Boolean("false") | true | Any non-empty string is truthy — even the word "false"! |
Boolean(null) | false | Null represents intentional absence, so it is falsy. |
Boolean(undefined) | false | Undefined means no value has been assigned — falsy. |
Common truthy/falsy evaluations
SECTION 6
Worked Example — Debugging a Type Bug
Let's walk through a realistic scenario. You are building a simple calculator page. A user types "7" and "3" into two text inputs, then clicks an "Add" button. Your code reads these values and computes the sum. But the result displayed is "73" instead of 10. Let's figure out what went wrong and fix it.
Fixing String + Number Concatenation
- 1
Step 1 — Identify the Values
Text inputs always return strings. So even though the user typed digits, JavaScript seeslet a = "7";andlet b = "3";. Usetypeof ato confirm: it returns"string".typeof a → "string",typeof b → "string" - 2
Step 2 — Understand the Bug
The expressiona + bevaluates as"7" + "3". Since both operands are strings, the+operator concatenates them instead of adding."7" + "3" → "73"(string concatenation, not addition) - 3
Step 3 — Convert Types
To force numeric addition, convert the strings to numbers usingNumber(). WriteNumber(a) + Number(b). Now both values are type"number".Number("7") + Number("3") → 7 + 3 → 10 - 4
Step 4 — Verify the Fix
Check withtypeofagain:typeof Number(a)returns"number". The result is now correctly10— a number, not a string.Final result: 10 (number)
Pro Tip
+ operator: +"7" returns 7. So +a + +b works too, though Number() is easier to read.SECTION 7
Comparisons — Null vs. Undefined and == vs. ===
One of the trickiest parts of JavaScript types is understanding the difference between null and undefined, and how equality operators treat different types. JavaScript has two equality operators: the loose equality operator == (which coerces types before comparing) and the strict equality operator === (which does not coerce and checks both value and type). Most professional developers strongly prefer === because it removes ambiguity.
| Expression | Result | Explanation |
|---|---|---|
null == undefined | true | Loose equality considers them equivalent — both mean "no value." |
null === undefined | false | Strict equality says they are different types. |
0 == false | true | Loose equality coerces false to 0, then compares 0 to 0. |
0 === false | false | Strict equality sees number vs. boolean — different types. |
"" == false | true | Both coerce to 0 under loose equality. |
"" === false | false | String vs. boolean — strict equality rejects. |
Loose (==) vs. Strict (===) equality with different types
KEY TAKEAWAY
=== as checking that two packages are the exact same item and the same wrapping, while == rips off the wrapping first and just looks at what's inside. Using === is like being precise — it avoids mismatches that loose equality hides. As a rule, default to === unless you have a specific reason to use ==.SECTION 8
Connection to Advanced Concepts
The five primitive types you learned here form the foundation, but JavaScript's type system goes much further. As you advance, you will encounter objects (which include arrays, functions, and custom objects), and eventually tools like TypeScript — a superset of JavaScript that adds static typing. Understanding primitive types now prepares you for all of these.
| Concept (This Lesson) | Advanced Version |
|---|---|
| Five primitive types (number, string, boolean, null, undefined) | Seven primitives in modern JS — adds Symbol (ES6) and BigInt (ES2020) for unique identifiers and large integers. |
| Dynamic typing — types checked at runtime | TypeScript adds compile-time type checking, catching type errors before code even runs. |
| Type coercion with + and == | The Abstract Equality Comparison Algorithm (ECMAScript spec) defines every coercion step formally. |
| typeof operator for checking types | instanceof, Object.prototype.toString.call(), and TypeScript type guards provide more precise type checking. |
| Falsy/truthy values | Optional chaining (?.) and nullish coalescing (??) operators give fine-grained control over null/undefined checks. |
From fundamentals to advanced type concepts
Don't worry about memorizing these advanced topics now. The key insight is that everything you will learn about JavaScript objects, classes, and even frameworks like React traces back to understanding what type a value is and how that type influences computation. Mastering the five primitives gives you a mental model that scales.
SECTION 9
Practice Problems
Question 1: CONCEPTUAL
null and undefined in JavaScript. Give a real-world analogy for each.Show answer
undefined means a variable has been declared but no value has been assigned to it yet — like a mailbox that exists but has never received any mail. null means the programmer has intentionally set a variable to "no value" — like a mailbox where someone deliberately emptied it and left a note saying "nothing here." Both represent the absence of a meaningful value, but undefined is typically assigned by the engine, while null is assigned by the programmer.Question 2: BASIC CALCULATION
"10" + 5
b) "10" - 5
c) true + 1Show answer
"105" — a string. The + operator sees a string on the left, so it converts 5 to "5" and concatenates. b) 5 — a number. The - operator only works with numbers, so "10" is coerced to 10, and 10 − 5 = 5. c) 2 — a number. true coerces to 1 in arithmetic, so 1 + 1 = 2.Question 3: INTERMEDIATE
let score; is declared but not assigned. What will each of the following log to the console?
a) console.log(typeof score);
b) console.log(score + 10);
c) console.log(score == null);
d) console.log(score === null);Show answer
"undefined" — the variable was declared but has no value. b) NaN — undefined coerces to NaN in arithmetic, and NaN plus any number is NaN. c) true — loose equality treats null and undefined as equal to each other. d) false — strict equality checks the type as well: undefined is not the same type as null, so it returns false. This illustrates why === is the safer choice.Question 4: APPLIED
let fahrenheit = document.getElementById("tempInput").value;. You then compute: let celsius = (fahrenheit - 32) * 5 / 9; — If the user types 212, does this formula work correctly even though fahrenheit is a string? Explain why, and identify one related expression where it would fail.Show answer
-, *, and / operators only work with numbers, so JavaScript automatically coerces "212" to 212. The result is (212 − 32) × 5 / 9 = 100. However, if you wrote fahrenheit + 10 to add an offset, you would get "21210" (concatenation) instead of 222. It's best practice to explicitly convert with Number(fahrenheit) to avoid any coercion surprises.Question 5: CRITICAL THINKING
let a = "5";
let b = 3;
let c = a + b;
let d = a - b;
console.log(c, typeof c);
console.log(d, typeof d);
console.log(c == 53);
console.log(c === 53);
Predict all four console outputs. Then explain why c == 53 and c === 53 give different results, connecting your answer to at least two concepts from this lesson.Show answer
"53" string — the + operator concatenates because a is a string. Line 2: 2 number — the - operator forces numeric coercion, so "5" becomes 5, and 5 − 3 = 2. Line 3: true — loose equality (==) coerces the string "53" to the number 53, which equals 53. Line 4: false — strict equality (===) checks both value and type: "53" is a string but 53 is a number, so they are not strictly equal. This problem demonstrates two key concepts: type coercion (how + concatenates with strings while - converts to numbers) and the difference between loose and strict equality (== coerces, === does not).SUMMARY
Lesson Summary
Summary
JavaScript has five fundamental primitive types: number (integers, decimals, NaN, Infinity), string (text in quotes), boolean (true/false), null (intentional absence), and undefined (not yet assigned). The typeof operator reveals a value's type at runtime, which is your primary debugging tool for type-related bugs.
Types determine how expressions behave. The + operator concatenates when a string is present but adds when both sides are numbers — this is type coercion in action. Every value is either truthy or falsy when placed in a boolean context (if-statements, loops). Always prefer strict equality (===) over loose equality (==) to avoid unexpected coercion. When reading user input, explicitly convert strings to numbers using Number() before performing arithmetic.