Skip to main content

JavaScript Errors

JavaScript Debugging

Written by Published

Debugging is the process of finding out why code does not do what you expected.

Most bugs come from an assumption that turns out to be wrong.

Debugging is mostly about checking those assumptions one at a time.

Example

Example

javascript

const price = "10";
const quantity = 2;

console.log(typeof price, typeof quantity);
console.log(price * quantity);

Printing the types immediately shows the problem.

Here it happens to work, but addition would not.

The Console Methods

console.log prints values.

console.table shows arrays of objects as a grid.

console.error and console.warn stand out from ordinary output.

Syntax

Syntax

javascript

console.log("label", value);
console.table(arrayOfObjects);

Always label what you print, or you lose track.

Label Everything

Printing a bare value tells you nothing once there are several.

A label costs nothing and saves confusion.

Example

Example

javascript

const width = 4;
const height = 5;

console.log("width", width);
console.log("height", height);
console.log("area", width * height);

Passing the variable in braces prints the name too, in modern browsers.

Check the Type, Not Just the Value

"10" and 10 look identical when printed.

Example

Example

javascript

const a = "10";
const b = 10;

console.log(a, b);
console.log(typeof a, typeof b);
console.log(a === b);

The types explain a whole category of confusing bugs.

Narrow It Down

Print at a few points to find where the value stops being right.

The bug is always between the last good print and the first bad one.

Example

Example

javascript

function process(values) {
  const stages = [];
  const doubled = values.map(function (n) { return n * 2; });
  stages.push("after doubling: " + doubled.join(","));
  const kept = doubled.filter(function (n) { return n > 4; });
  stages.push("after filtering: " + kept.join(","));
  return stages.join(" | ");
}

console.log(process([1, 2, 3]));

Now you can see exactly which stage produced the wrong list.

console.table

Far easier to read than a list of objects.

Example

Example

javascript

const users = [
  { name: "Ada", age: 36 },
  { name: "Grace", age: 45 }
];

console.log(users.length + " users");
console.log(users.map(function (u) { return u.name; }).join(", "));

In a browser, console.table(users) shows this as a grid.

The debugger Statement

It pauses execution when developer tools are open.

Then you can inspect every variable at that moment.

Example

Example

javascript

function calculate(a, b) {
  const result = a + b;
  return result;
}

console.log(calculate(2, 3));

Adding debugger; inside would stop it there for inspection.

Complete Example

Complete Example

html

<!DOCTYPE html>
<html>
<head>
  <title>JavaScript Debugging</title>
</head>
<body>

  <h1>Debugging</h1>

  <p id="out"></p>

  <script>
    const price = "10";
    const quantity = 2;

    console.log("price", price, typeof price);
    console.log("quantity", quantity, typeof quantity);

    const total = Number(price) * quantity;
    console.log("total", total);

    document.getElementById("out").innerHTML =
      "Open the console to see the values.<br>Total: " + total;
  </script>

</body>
</html>

Try It Yourself

Run the above example in the Try It Editor.

Try removing the conversion:

Use price + quantity and watch the types explain the result.

Important Points

  • Most bugs are a wrong assumption about a value.
  • Always label what you print.
  • Check the type as well as the value.
  • Print at several points to narrow down where it breaks.
  • debugger pauses execution for inspection.

Conclusion

Debugging is a systematic process, not guesswork.

Checking types finds a surprising share of JavaScript bugs.

Narrowing down the range beats staring at the whole function.