Home Module 09 Data Types

1. Introduction

Every value in JavaScript has a type. The type determines what you can do with the value — you can multiply numbers, join strings, and check truth/falsehood of booleans, but you cannot multiply strings or check if a number is true.

JavaScript has 7 primitive types and one complex type (object):

TypeExampleUsed for
string'Hello'Text
number42, 3.14Integers and decimals
booleantrue, falseYes/no, on/off logic
undefinedundefinedVariable declared but not assigned
nullnullIntentionally empty / no value
bigint9007199254740991nVery large integers
symbolSymbol('id')Unique identifiers (advanced)
object{ name: 'Alice' }, [1,2,3]Collections of data

This lesson focuses on the four you will use constantly: string, number, boolean, undefined, and null.

2. Theory

2.1 String

A string is a sequence of characters — text. Wrap it in single quotes, double quotes, or backticks (template literals).

const single   = 'Hello, World!';
const double   = "Hello, World!";
const template = `Hello, World!`;

// All three are identical strings
console.log(single === double); // true

Template literals (backticks) — the modern way

Backtick strings can embed expressions with ${ } and span multiple lines:

const name = 'Alice';
const age  = 30;

// Old way — string concatenation
const msg1 = 'Hello, ' + name + '! You are ' + age + ' years old.';

// Modern way — template literal
const msg2 = `Hello, ${name}! You are ${age} years old.`;

console.log(msg2); // Hello, Alice! You are 30 years old.

// Multi-line
const poem = `Roses are red,
Violets are blue,
JavaScript is awesome,
And so are you.`;

Useful string methods

const text = 'Hello, World!';

text.length          // 13 — number of characters
text.toUpperCase()   // 'HELLO, WORLD!'
text.toLowerCase()   // 'hello, world!'
text.includes('World')  // true
text.startsWith('Hello') // true
text.endsWith('!')   // true
text.indexOf('o')    // 4 — position of first 'o'
text.slice(0, 5)     // 'Hello'
text.replace('World', 'JS') // 'Hello, JS!'
text.trim()          // removes whitespace from both ends
text.split(', ')     // ['Hello', 'World!']
'  spaces  '.trim()  // 'spaces'

2.2 Number

JavaScript has a single number type for both integers and decimals (stored as 64-bit floating point).

const integer  = 42;
const decimal  = 3.14;
const negative = -10;

// Basic arithmetic
console.log(10 + 3);  // 13
console.log(10 - 3);  // 7
console.log(10 * 3);  // 30
console.log(10 / 3);  // 3.3333...
console.log(10 % 3);  // 1  (remainder)
console.log(2 ** 8);  // 256 (exponentiation)

Special number values

console.log(1 / 0);       // Infinity
console.log(-1 / 0);      // -Infinity
console.log('hello' * 2); // NaN (Not a Number)
console.log(isNaN('abc')); // true
console.log(isFinite(1/0)); // false

Useful number methods and functions

const n = 3.14159;
n.toFixed(2)       // '3.14' — string with 2 decimal places
n.toFixed(0)       // '3'
Math.round(3.7)    // 4
Math.floor(3.9)    // 3 — round down
Math.ceil(3.1)     // 4 — round up
Math.abs(-5)       // 5 — absolute value
Math.max(1, 5, 3)  // 5
Math.min(1, 5, 3)  // 1
Math.random()      // 0 to 0.999... (random decimal)
Math.sqrt(16)      // 4
Number('42')       // 42 — convert string to number
parseInt('42px')   // 42 — parse integer from string
parseFloat('3.14') // 3.14

2.3 Boolean

A boolean has exactly two possible values: true or false. It represents yes/no, on/off, success/failure.

const isLoggedIn = true;
const hasDiscount = false;
const isAdult = age >= 18; // evaluates to true or false

console.log(isLoggedIn);  // true
console.log(typeof isLoggedIn); // 'boolean'

Truthy and falsy values

In JavaScript, every value is either "truthy" (behaves like true in a boolean context) or "falsy" (behaves like false).

Falsy values (only 6 of them):

false
0
''        // empty string
null
undefined
NaN

Everything else is truthy, including: 1, -1, '0' (string "0"), 'false' (string "false"), [] (empty array), {} (empty object).

if (0)         { /* never runs */ }
if ('')        { /* never runs */ }
if (null)      { /* never runs */ }
if ('hello')   { /* always runs — truthy */ }
if ([])        { /* always runs — truthy */ }
if (42)        { /* always runs — truthy */ }

2.4 undefined

undefined means a variable has been declared but not yet assigned a value. It is set automatically by JavaScript.

let score;
console.log(score); // undefined
console.log(typeof score); // 'undefined'

// Also returned by functions that have no return statement
function doNothing() {}
console.log(doNothing()); // undefined

// And by accessing a property that doesn't exist
const user = { name: 'Alice' };
console.log(user.email); // undefined

2.5 null

null means an intentional absence of value — "there is no value here, on purpose." You explicitly set something to null to clear it.

let selectedUser = null; // no user selected yet

// After user logs in
selectedUser = { name: 'Alice', id: 1 };

// After user logs out
selectedUser = null; // explicitly clear it

null vs undefined: undefined means "not set yet." null means "deliberately empty."

2.6 The typeof operator

typeof returns a string describing the type of a value:

typeof 'hello'     // 'string'
typeof 42          // 'number'
typeof 3.14        // 'number'
typeof true        // 'boolean'
typeof undefined   // 'undefined'
typeof null        // 'object'  ← famous JS bug, null is not an object
typeof {}          // 'object'
typeof []          // 'object'
typeof function(){} // 'function'
Note: typeof null === 'object' is a long-standing bug in JavaScript that was never fixed to avoid breaking existing code. To check for null, use value === null.

2.7 Type conversion

JavaScript converts types automatically (implicit) or you can convert manually (explicit).

// Implicit (automatic) — beware
console.log('5' + 3);   // '53' — number converted to string (concatenation)
console.log('5' - 3);   // 2   — string converted to number (subtraction)
console.log(true + 1);  // 2   — true converted to 1

// Explicit (manual) — preferred
Number('42')    // 42
Number('hello') // NaN
Number(true)    // 1
Number(false)   // 0
Number(null)    // 0

String(42)      // '42'
String(true)    // 'true'
String(null)    // 'null'

Boolean(1)      // true
Boolean(0)      // false
Boolean('')     // false
Boolean('hi')   // true

3. Real World Example

A form validation function uses different data types:

function validateSignup(username, age, agreeToTerms) {
  // username is a string — check it's not empty and long enough
  if (typeof username !== 'string' || username.trim().length < 3) {
    return 'Username must be at least 3 characters.';
  }

  // age comes from an input as a string — convert it
  const ageNum = Number(age);
  if (isNaN(ageNum) || ageNum < 13) {
    return 'You must be at least 13 years old.';
  }

  // agreeToTerms is a boolean
  if (agreeToTerms !== true) {
    return 'You must agree to the terms.';
  }

  return null; // null = no error
}

console.log(validateSignup('Al', 25, true));   // 'Username must be...'
console.log(validateSignup('Alice', 10, true)); // 'You must be at least...'
console.log(validateSignup('Alice', 25, false)); // 'You must agree...'
console.log(validateSignup('Alice', 25, true));  // null (valid)

4. Code Example

<script>
  // ---- Strings ----
  const firstName = 'Alice';
  const lastName  = 'Smith';
  const fullName  = `${firstName} ${lastName}`;
  console.log(fullName);                    // Alice Smith
  console.log(fullName.toUpperCase());      // ALICE SMITH
  console.log(fullName.includes('Alice')); // true
  console.log(fullName.split(' '));        // ['Alice', 'Smith']

  // ---- Numbers ----
  const price = 29.99;
  const qty   = 3;
  const total = price * qty;
  console.log(`Total: $${total.toFixed(2)}`); // Total: $89.97
  console.log(Math.round(total));              // 90
  console.log(Math.random());                  // e.g. 0.6573...

  // ---- Booleans ----
  const isLoggedIn  = true;
  const hasCoupon   = false;
  const canCheckout = isLoggedIn && !hasCoupon;
  console.log('Can checkout:', canCheckout); // true

  // ---- null and undefined ----
  let selectedItem = null;
  console.log('Selected:', selectedItem);        // null
  console.log('Type:', typeof selectedItem);     // object (bug!)
  console.log('Is null?', selectedItem === null); // true

  let discount;
  console.log('Discount:', discount);  // undefined

  // ---- typeof ----
  console.log(typeof firstName); // string
  console.log(typeof price);     // number
  console.log(typeof isLoggedIn);// boolean

  // ---- Type conversion ----
  const inputAge = '25'; // from a text input — always a string!
  const numAge   = Number(inputAge);
  console.log(typeof inputAge, typeof numAge); // string number
  console.log(numAge >= 18 ? 'Adult' : 'Minor'); // Adult
</script>

5. Code Breakdown

Template literal (fullName)

`${firstName} ${lastName}` embeds the two string variables with a space. This is cleaner and easier to read than firstName + ' ' + lastName.

total.toFixed(2)

toFixed(2) is a number method that returns a string with exactly 2 decimal places. Useful for displaying prices. Note it returns a string, not a number — if you need to do further math, convert it back with Number().

isLoggedIn && !hasCoupon

Boolean operators: && means AND (both must be true). ! means NOT (flip the boolean). So canCheckout is true if the user is logged in AND does NOT have a coupon. You will learn all operators in Lesson 4.

selectedItem === null

Because typeof null === 'object' (a bug), always use strict equality === null to check for null.

Number(inputAge)

HTML input values are always strings. If you take a number from an input field and do arithmetic on it without converting, you may get string concatenation instead of addition. Always convert with Number() or parseInt()/parseFloat().

6. Common Mistakes

Mistake 1 — Forgetting that input values are strings

const input = '5'; // from a form input
console.log(input + 10); // '510' — string concatenation!
console.log(Number(input) + 10); // 15 — correct

Mistake 2 — Comparing null with typeof

const val = null;
console.log(typeof val === 'null');   // false — typeof null is 'object'
console.log(val === null);            // true — correct check

Mistake 3 — NaN is not equal to itself

const result = 'hello' * 2; // NaN
console.log(result === NaN); // false — NaN !== NaN
console.log(isNaN(result));  // true — use isNaN() instead
console.log(Number.isNaN(result)); // true — more reliable

Mistake 4 — Using == instead of ===

console.log(0 == false);   // true — type coercion!
console.log('' == false);  // true — type coercion!
console.log(null == undefined); // true — type coercion!

console.log(0 === false);  // false — no coercion, types differ
console.log('' === false); // false

// Always use === (strict equality)

Mistake 5 — Floating point precision

console.log(0.1 + 0.2); // 0.30000000000000004 — floating point issue!
console.log(0.1 + 0.2 === 0.3); // false

// Fix: round to a specific precision when comparing
console.log((0.1 + 0.2).toFixed(1) === '0.3'); // true
// Or multiply to work with integers: 10 cents + 20 cents = 30 cents

7. Best Practices

  1. Use strict equality (===) instead of loose equality (==) to avoid type coercion surprises.
  2. Always convert form input values with Number(), parseInt(), or parseFloat() before doing arithmetic.
  3. Use template literals (`${var}`) instead of string concatenation for readability.
  4. Check for null explicitly with === null, not with typeof.
  5. Use Number.isNaN() instead of the global isNaN() — it is more reliable.
  6. Distinguish null from undefined deliberately — use null for "intentionally empty," let JavaScript set undefined for "not yet assigned."
  7. For currency/money, work with integers (cents) and divide by 100 for display — never rely on floating-point arithmetic for exact currency calculations.

8. Practice Exercise

  1. Create variables for each primitive type (string, number, boolean, null, undefined). Log each value and its typeof.
  2. Write a sentence about yourself using a template literal with at least 3 embedded variables.
  3. Take the string ' Hello, World! '. Trim it, convert to uppercase, and check if it includes 'WORLD'.
  4. Create a random integer between 1 and 10 using Math.random(), Math.floor(), and multiplication.
  5. Write a function typeChecker(val) that logs the value, its typeof, and whether it is truthy or falsy.

Bonus

  • Build a mini tip calculator that takes a bill string from prompt(), converts it to a number, and logs the 15%, 18%, and 20% tip amounts using toFixed(2).

9. Assignment

Build a "User Profile Card" that uses every data type.

  1. Declare variables: name (string), age (number), isPremium (boolean), lastLogin (null), nickname (undefined initially).
  2. Build a profile summary string using a template literal and log it.
  3. Write a function describeUser(user) that accepts an object and logs a sentence for each field, handling null and undefined gracefully ("Not set").
  4. Use typeof inside the function to confirm each field's type.
  5. Display a "Premium Member" or "Free Member" badge based on isPremium.
  6. Convert age to a string with String(age) and verify with typeof.

Deliverable: A single HTML file. All output in the console.

10. Interview Questions

  1. What are the primitive data types in JavaScript?
    string, number, boolean, undefined, null, bigint, symbol. (Object is the only non-primitive.)
  2. What is the difference between null and undefined?
    undefined means a variable was declared but not assigned — JavaScript sets this automatically. null is an intentional absence of value — you set it explicitly to clear a reference.
  3. What are truthy and falsy values?
    Falsy values are: false, 0, '' (empty string), null, undefined, NaN. Everything else is truthy, including '0', 'false', [], and {}.
  4. Why should you use === instead of ==?
    == performs type coercion before comparing (e.g., 0 == false is true). === compares both value and type without coercion, giving predictable results.
  5. What does typeof return for null?
    'object' — this is a well-known historical bug in JavaScript. To check for null, use value === null.
  6. Why might 0.1 + 0.2 not equal 0.3 in JavaScript?
    JavaScript uses 64-bit floating-point arithmetic (IEEE 754), which cannot represent some decimal fractions exactly. The result is 0.30000000000000004. For exact currency calculations, use integer arithmetic (work in cents).

11. Additional Resources

  • MDN — JavaScript data types and data structures
  • javascript.info — Data types — excellent beginner-friendly breakdown
  • MDN — typeof operator
  • javascript.info — Type Conversions
  • MDN — String methods reference
  • MDN — Math object reference