JavaScript Roadmap — Day 5: Undefined, Null, and typeof

 

JavaScript · Day 5 of 180 · Beginner Phase

Undefined, Null, and typeof

Two values that mean "nothing" — but in completely different ways. This is where most beginners get permanently confused. Today we fix that forever.

Day 5 / 180
Beginner Phase

Imagine you order food at a restaurant. The waiter comes back and says one of two things:

🧑‍🍳 "I haven't checked yet whether we have that dish." → This is undefined

🧑‍🍳 "I checked. We deliberately do not have it on the menu." → This is null

Both mean "no value" — but one means not yet known and the other means intentionally empty. This distinction sounds small but it causes real bugs in real projects every single day. By the end of this lesson you will never confuse them again.

1. undefined — JavaScript Says "I Don't Know Yet"

undefined is what JavaScript gives you automatically when something has been declared but not given a value yet. You never need to write undefined yourself — JavaScript assigns it on its own in these situations:

Situation Result
Variable declared but not assigned undefined
Function returns nothing undefined
Accessing object property that does not exist undefined
Function called with missing argument undefined
JavaScript
// 1. Variable declared but not assigned
let username;
console.log(username); // undefined

// 2. Function with no return statement
function greet() {
  // no return here
}
let result = greet();
console.log(result); // undefined

// 3. Object property that does not exist
let user = { name: "Waheed" };
console.log(user.age);  // undefined (age was never set)

// 4. Missing function argument
function add(a, b) {
  console.log(b); // undefined — b was never passed
  return a + b;
}
add(5); // only passed one argument

💡 The golden rule: You should never manually assign undefined to a variable. If you want to say "this has no value intentionally" — use null instead. undefined is JavaScript's job, not yours.

2. null — You Say "This is Intentionally Empty"

null is something you write yourself to say: "I know this variable exists, and I am deliberately saying it has no value right now." It is a conscious decision — not an accident like undefined.

Real world use cases for null — when you have a variable whose value will come later, when you want to clear a value, or when a function finds nothing to return:

JavaScript
// null = intentional empty value
let selectedUser = null; // no user selected yet
let profilePicture = null; // user has not uploaded one yet

// After user logs in — now we give it a real value
selectedUser = { name: "Waheed", age: 22 };

// After user logs out — we clear it back to null
selectedUser = null;

// Function returning null when nothing is found
function findUser(id) {
  let users = [{ id: 1, name: "Waheed" }];
  let found = users.find(u => u.id === id);
  return found || null; // explicitly return null if not found
}

console.log(findUser(1)); // { id: 1, name: "Waheed" }
console.log(findUser(99)); // null

3. The Most Famous Bug in JavaScript History 🐛

Run this in any JavaScript console and you will see something that makes no logical sense:

JavaScript
typeof null  // "object" ← WAIT WHAT?!
typeof undefined  // "undefined" ← this makes sense

null is not an object. It never was. This is a bug from 1995 — the very first version of JavaScript written in just 10 days by Brendan Eich. In the original JavaScript engine, values were stored with a type tag. The tag for objects was 000. And null was represented as a null pointer — which was also 000. So the engine incorrectly read null as an object type.

The bug was discovered immediately. But by then JavaScript was already running in millions of browsers. Fixing it would break every website on the internet. So the decision was made: keep the bug forever. And here we are in 2026 — still living with a 30-year-old mistake. This is why you always use strict equality when checking for null.

JavaScript
// WRONG way to check for null
if (typeof value === "object") {
  // This is true for null AND for real objects!
  // Dangerous — you may accidentally treat null as an object
}

// CORRECT way to check for null
if (value === null) {
  console.log("value is null");
}

// CORRECT way to check for null OR undefined together
if (value == null) {
  // == (loose) catches BOTH null and undefined
  // This is one of the only good uses of == in modern JS
  console.log("value is null or undefined");
}

4. == vs === with null and undefined — The Brain Bender 🔥

This is where most beginners get confused permanently. Pay close attention — these four results will surprise you:

JavaScript
null == undefined   // true  ← loose equality, they are "equal"
null === undefined  // false ← strict equality, different types

null == 0          // false ← null only equals null or undefined
null == ""         // false ← same rule
null == false      // false ← null is special, not just any falsy value

undefined == 0     // false
undefined == ""    // false
undefined == false // false

// The rule: null and undefined ONLY equal each other
// with ==. They do NOT equal anything else.

🔥 Mind shift: Most beginners think null and false and 0 and "" are all "equal" with ==. They are not. null and undefined are a special pair — they only equal each other and nothing else when using loose equality.

5. The void Operator — Always Returns undefined

Most tutorials never mention this. The void operator evaluates an expression and always returns undefined. You will see it in old codebases and occasionally in modern JavaScript for specific tricks:

JavaScript
// void always returns undefined
console.log(void 0);        // undefined
console.log(void "hello");  // undefined
console.log(void true);    // undefined

// Common use: prevent link from navigating
// <a href="javascript:void(0)">Click me</a>
// This is how old code prevented page reloads

// Modern use: safely get undefined
// In very old JS, someone could write: undefined = "something"
// void 0 always guaranteed true undefined
const safeUndefined = void 0;

6. Nullish Coalescing — The Modern Solution (??)

This is a modern operator added in ES2020. It solves a very common real-world problem — giving a default value when something is null or undefined, but not when it is 0 or false or an empty string.

Before ?? was invented, developers used || for defaults. But || has a hidden bug — it treats 0, false, and "" as falsy and replaces them with the default even when they are valid values. The ?? operator only triggers for null and undefined — nothing else:

JavaScript
// The OLD way using || (has a bug)
let score = 0;
let display = score || "No score";
console.log(display); // "No score" ← WRONG! Score IS 0, that is valid!

// The NEW way using ?? (correct)
let score2 = 0;
let display2 = score2 ?? "No score";
console.log(display2); // 0 ← CORRECT! 0 is a valid score

// ?? only triggers for null and undefined
console.log(null ?? "default");      // "default"
console.log(undefined ?? "default"); // "default"
console.log(0 ?? "default");         // 0 (not replaced!)
console.log("" ?? "default");        // "" (not replaced!)
console.log(false ?? "default");     // false (not replaced!)

// Real world example
function showUserName(name) {
  return name ?? "Guest";
}
console.log(showUserName("Waheed")); // "Waheed"
console.log(showUserName(null));      // "Guest"
console.log(showUserName(undefined)); // "Guest"
Pro Tip #1 — undefined is a type, null is not
typeof undefined returns "undefined" — its own type. But typeof null returns "object" — because of the 30-year-old bug. This is why you never use typeof to check for null. Always use === null directly.
Pro Tip #2 — Optional chaining stops crashes
Accessing a property on null crashes your app with a TypeError. Use optional chaining ?. to safely access nested values. user?.address?.city returns undefined if any part is null or undefined — instead of throwing an error. This is one of the most used modern JavaScript features in production code.
Pro Tip #3 — Both are falsy but behave differently in math
Both null and undefined are falsy — they both fail an if condition. But in arithmetic they behave differently. null + 1 gives 1 because null converts to 0. But undefined + 1 gives NaN because undefined cannot be converted to a number. This difference causes real bugs.

Quick Reference

Check undefined null
typeof "undefined" "object" ← bug
Boolean context falsy falsy
In arithmetic NaN 0
JSON.stringify removed from output kept as null
Who sets it JavaScript automatically You intentionally
== null true true
=== null false true

Try It Yourself

Edit the code and click Run Code. Try changing values and observe the differences between null and undefined in every situation.

✏️ Try it Yourself — Undefined & Null
OUTPUT
// Click Run Code to see output
💡 Code edit karo aur Run dabao!

Practice Tasks

Task 1 — Easy: Spot the Difference

Declare a variable without assigning a value. Log it and check its type. Then set it to null and log it again. Write in comments what changed and why.

Task 2 — Medium: Fix the Default Value Bug

A function receives a score parameter. If score is null or undefined, show "No score yet". But if score is 0, show 0 — not the default message. Write this using ?? and also the wrong way using || to see the difference.

Task 3 — Hard: The Crash Prevention Challenge

You have this object: let user = null. Try to access user.address.city — it will crash. Now fix it using optional chaining ?. so it returns undefined instead of crashing. Then use ?? to show "City unknown" as the fallback. This exact pattern is used in every real application.

Next Lesson
Day 6 — Type Conversion and Coercion
Read Next Lesson →
Want daily web dev tips?
Follow Muhammad Waheed Asghar for daily JavaScript and CSS tips!