Debugging
Common Bugs & Fixes
Most bugs fall into a handful of recurring categories. Recognizing them on sight saves enormous time.
Cannot read properties of undefined
The most common JavaScript error — accessing a property on undefined or null.
const user = users.find((u) => u.id === 99); // not found → undefined
console.log(user.name); // 💥 Cannot read properties of undefined
// Fixes:
console.log(user?.name); // optional chaining
const name = user?.name ?? "Guest"; // with a default
if (user) console.log(user.name); // guard
Assignment vs comparison
if (status = "active") { } // ❌ assigns, always truthy
if (status === "active") { } // ✅ compares
Off-by-one and loop bugs with var
// ❌ var is function-scoped — all handlers log the final i
for (var i = 0; i < 3; i++) {
buttons[i].onclick = () => console.log(i); // always 3
}
// ✅ let creates a new binding each iteration
for (let i = 0; i < 3; i++) {
buttons[i].onclick = () => console.log(i); // 0, 1, 2
}
Async timing bugs
// ❌ returns before the async work finishes
function getData() {
fetch("/api").then((r) => r.json()).then((d) => (data = d));
return data; // undefined!
}
// ✅ await the result
async function getData() {
const res = await fetch("/api");
return res.json();
}
Mutating instead of copying
const copy = original; // ❌ same reference — mutating copy mutates original
copy.push(4);
const copy = [...original]; // ✅ a real shallow copy
💡
Floating-point surprise: 0.1 + 0.2 === 0.3 is false (it's 0.30000000000000004). Never compare floats with ===; use a small tolerance instead.
Watch & Learn
A recommended video to watch alongside this chapter.
More “Common Bugs & Fixes” videos on YouTube