5 Debugging JavaScript
- Understand how JavaScript handles errors and stops code execution at error points
- Identify and fix common syntax errors including mismatched quotes, brackets, and braces
- Recognize and resolve reference errors and type errors
- Use systematic debugging strategies including console.log() and browser developer tools
- Apply step-by-step debugging processes to isolate and fix problems
- Prevent common bugs through good coding practices and testing approaches
Debugging is an essential skill for any programmer. When your code doesn’t work as expected, systematic debugging helps you identify and fix the problem quickly. As a beginner, you’ll encounter certain types of errors frequently. Learning to recognize and resolve them will make you a more confident programmer.
5.1 How JavaScript Handles Errors
Important: When JavaScript encounters an error, it stops executing your code at that exact point. This behavior is actually helpful for debugging because it tells you precisely where the problem occurred.
console.log("This line runs");
console.log("This line also runs");
let result = someUndefinedVariable + 5; // Error occurs here
console.log("This line NEVER runs"); // Code stops at the error above
console.log("Neither does this line");
Console output:
This line runs
This line also runs
ReferenceError: someUndefinedVariable is not defined
at script.js:3:14
Notice that the last two console.log()
statements never execute because JavaScript stopped when it hit the error on line 3.
5.1.1 Using This to Your Advantage
You can use JavaScript’s “stop on error” behavior to narrow down where problems occur:
console.log("Step 1: Starting the program");
let numbers = [1, 2, 3];
console.log("Step 2: Created array");
let sum = 0;
console.log("Step 3: Initialized sum");
// If you see "Step 3" but not "Step 4" in the console,
// you know the error is in the next line
for (let i = 0; i <= numbers.length; i++) { // Bug: should be < not <=
console.log("Step 4: In loop, i =", i);
sum += numbers[i]; // This will error when i = 3 (undefined)
}
console.log("Step 5: Loop finished"); // This won't run if there's an error above
If you see steps 1-3 but the program stops there, you know the problem is in the loop.
5.2 Common Types of JavaScript Errors
5.2.1 Syntax Errors
These occur when your code violates JavaScript’s grammar rules. The browser can’t even run your code when syntax errors are present. These are often the most frustrating for beginners because they prevent any code from running.
5.2.1.1 Missing or Mismatched Quotation Marks
Single vs. Double Quote Mismatches:
5.2.1.2 Missing Brackets and Braces
Array Brackets [ ]
:
// Wrong - missing closing bracket
let colors = ["red", "blue", "green"; // Error: missing ]
let numbers = [1, 2, 3, 4, 5; // Error: missing ]
// Wrong - missing opening bracket
let colors = "red", "blue", "green"]; // Error: missing [
// Correct
let colors = ["red", "blue", "green"];
Object Braces { }
:
// Wrong - missing closing brace
let person = {
name: "Alice",
age: 25
; // Error: missing }
// Wrong - missing opening brace
let person =
name: "Alice",
age: 25
}; // Error: missing {
// Correct
let person = {
name: "Alice",
age: 25
};
Function Parentheses ( )
and Braces { }
:
5.2.1.3 Complex Nested Structures
When you combine arrays, objects, and strings, tracking matching symbols becomes challenging:
Wrong - Multiple syntax errors:
let students = [
{
name: "Alice, // Error: missing closing quote
grades: [85, 92, 78, // Error: missing closing bracket
info: "Honor student"
}, // Error: missing closing brace for first object
{
name: "Bob",
grades: [76, 88, 91],
info: "Regular student"
}
; // Error: missing closing bracket for arra
Correct version:
let students = [
{
name: "Alice", // Fixed: added closing quote
grades: [85, 92, 78], // Fixed: added closing bracket
info: "Honor student"
}, // Fixed: proper object closing
{
name: "Bob",
grades: [76, 88, 91],
info: "Regular student"
}
]; // Fixed: added closing bracket for array
Other Common Syntax Errors:
// Missing semicolon (usually not critical, but good practice)
let name = "John"
console.log(name)
// Missing comma in arrays or objects
let colors = ["red" "blue", "green"]; // Missing comma after "red"
let person = {
name: "Alice"
age: 25 // Missing comma after "Alice"
};
How to spot syntax errors: They usually prevent your code from running at all, and the browser console will show error messages like:
- SyntaxError: Unexpected token
- SyntaxError: Unterminated string literal
- SyntaxError: Unexpected end of input
- SyntaxError: Missing ) after argument list
5.2.2 Reference Errors
These happen when you try to use a variable that doesn’t exist or hasn’t been declared yet.
5.2.3 Type Errors
These occur when you try to perform an operation on a value that doesn’t support that operation.
5.2.4 Logic Errors
These are the trickiest because your code runs without error messages, but it doesn’t do what you intended.
5.2.5 Matching and Closing Syntax Errors
These are among the most common syntax errors beginners encounter, especially when working with complex data structures that mix text, arrays, and objects. JavaScript requires that every opening symbol has a matching closing symbol.
5.3 Debugging Strategies
5.3.1 Read Error Messages Carefully
Error messages might seem intimidating, but they contain valuable information:
Error message example: ReferenceError: userName is not defined // at script.js:5:13
This tells you:
- Type of error: ReferenceError
- What’s wrong: userName is not defined
- Where: script.js, line 5, character 13
5.3.2 Use console.log() for Debugging
This is your best friend for understanding what your code is actually doing:
let numbers = [1, 2, 3, 4, 5];
let sum = 0;
console.log("Starting sum:", sum); // Check initial value
for (let i = 0; i < numbers.length; i++) {
console.log("Current number:", numbers[i]); // Check each iteration
sum += numbers[i];
console.log("Sum so far:", sum); // Check running total
}
console.log("Final sum:", sum); // Check final result
5.3.3 Visual Debugging for Syntax Errors
Use proper indentation to see structure clearly:
// Hard to debug - poor indentation
let data = [{name: "Alice", scores: [85, 92]}, {name: "Bob", scores: [76, 88]}];
// Easy to debug - good indentation
let data = [
{
name: "Alice",
scores: [85, 92]
},
{
name: "Bob",
scores: [76, 88]
}
];
Count your symbols. Every opening symbol needs a closing one:
let complex = [ // 1 opening [
{ // 1 opening {
name: "test", // quotes match ✓
data: [1, 2] // 1 opening [, 1 closing ] ✓
} // 1 closing } ✓
]; // 1 closing ] ✓
Use your code editor’s features:
- Most editors highlight matching brackets/braces
- Many editors show syntax errors with red underlines
- Some editors auto-complete closing symbols
5.3.4 Check Your Variable Values
Often bugs happen because variables don’t contain what you think they do:
let userInput = "25"; // This is a string, not a number!
let age = userInput + 5;
console.log("Age:", age); // Output: "255" (string concatenation)
// Debug by checking the type
console.log("Type of userInput:", typeof userInput);
console.log("Value of userInput:", userInput);
// Fix by converting to number
let age = parseInt(userInput) + 5;
console.log("Corrected age:", age); // Output: 30
5.3.5 Isolate the Problem
When you have a lot of code, narrow down where the problem occurs:
// Instead of running everything at once, test parts separately
function calculateTotal(price, tax) {
console.log("Price:", price, "Tax:", tax); // Debug inputs
let total = price + (price * tax);
console.log("Calculated total:", total); // Debug output
return total;
}
// Test with known values
let result = calculateTotal(100, 0.08);
console.log("Final result:", result);
5.3.6 Use the Browser Developer Tools
Opening Developer Tools: - Chrome/Edge: Press F12 or Ctrl+Shift+I (Cmd+Option+I on Mac) - Firefox: Press F12 or Ctrl+Shift+I (Cmd+Option+I on Mac)
Console Tab: Shows error messages and console.log() output
Sources Tab: Lets you set breakpoints to pause code execution
5.3.7 Step-by-Step Debugging Process
When you encounter a bug, follow this systematic approach:
- Read the error message (if there is one) and note the line number
- Check that line and the lines around it for obvious mistakes
- For syntax errors: Count opening and closing symbols - they should match
- Add console.log() statements before and after the problematic area
- Run your code and examine the console output
- Compare expected vs. actual values in your console logs
- Make one small change at a time and test again
- Remove debugging console.log() statements once the bug is fixed
5.3.8 Prevention Tips
- Write code in small pieces and test each piece before moving on
- Use meaningful variable names to avoid confusion
- Be consistent with your coding style (indentation, spacing, naming)
- Comment your code to remember what each part does
- Test with different inputs to catch edge cases
5.3.9 Common Beginner Debugging Mistakes
- Assuming the error is complex when it’s often something simple like a typo
- Changing multiple things at once instead of testing one change at a time
- Not reading error messages carefully
- Forgetting to save files before testing changes
- Looking at the wrong file or line number
Remember: every programmer, no matter how experienced, spends time debugging. It’s a normal and important part of the development process. The key is to approach it systematically and learn from each bug you encounter.
5.4 Debugging Example
Let’s walk through debugging a common beginner mistake:
// Buggy code: trying to calculate average
let scores = [85, 92, 78, 96, 88];
let total = 0;
for (let i = 0; i <= scores.length; i++) { // Bug: should be < not <=
total += scores[i];
}
let average = total / scores.length;
console.log("Average:", average); // Output: NaN (Not a Number)
Debugging steps:
// Step 1: Add debugging to see what's happening
let scores = [85, 92, 78, 96, 88];
let total = 0;
console.log("Array length:", scores.length); // Debug: check array size
for (let i = 0; i <= scores.length; i++) {
console.log("Index:", i, "Value:", scores[i]); // Debug: check each iteration
total += scores[i];
console.log("Total so far:", total); // Debug: check running total
}
let average = total / scores.length;
console.log("Final total:", total); // Debug: check final total
console.log("Average:", average);
Console output reveals the problem:
Array length: 5
Index: 0 Value: 85
Total so far: 85
Index: 1 Value: 92
Total so far: 177
Index: 2 Value: 78
Total so far: 255
Index: 3 Value: 96
Total so far: 351
Index: 4 Value: 88
Total so far: 439
Index: 5 Value: undefined // Problem! Index 5 doesn't exist
Total so far: NaN // Adding undefined makes total NaN
The fix: