In this tutorial, you will learn techniques to help you successfully debug your JavaScript programs.
On September 9, 1947, Harvard computer scientists discovered the world’s first computer bug – a moth that crawled inside of their system and got stuck!
While we don’t often encounter literal bugs in our programs these days, computer “bugs” still persist in every level of programming, from the beginner to the seasoned professional. Debugging, or the act of finding and fixing the errors in our programs, is an important skill for all programmers to develop.
This tutorial looks at a few common sources of errors in programming with JavaScript and how to begin addressing them.
Before diving into the details of finding and fixing our bugs, the most important thing to know is that bugs occur at all levels of programming. It’s a nice fantasy to think that we can develop a program without them – bugs are attracted to programs, like, well, moths to a flame.
Knowing that bugs are inevitable, we must be ready for them to occur with patience and a detective’s mind. Yes they can be frustrating, but think of them as a mystery that, with the right tools, can be quite rewarding to solve.
The general debugging process looks something like these three steps:
Observe - something is broken, or not working as expected. Time to debug.
Investigate, Ask Questions, Sleuth, Try - what clues or information am I being given? What is not working? Where or when is the error occurring? What can I do to get more information, to find, or to isolate the problem?
Fix and Rebuild - fix the bug and slowly rebuild the program to make sure it’s working as expected.
As you can imagine, most of your time will be spent in step #2. Below we will introduce a few topics and skills to help you gather the information you need to find and remove any bugs that managed to crawl into your program.
In general there are two types of errors:
Syntax Related Errors - something is wrong with the code that either prevents the program from running or causes the program to crash at some point.
Logic Errors - the program runs fine, but it doesn’t do what you want it to do.
Syntax related errors often result in an error message being displayed when the program runs. These messages can provide clues as to what went wrong and where in the code the error may exist.
The first step with these errors is to see what you can learn from the messages.
Did I forget to define a variable or accidentally misspell it?
Did I forget a bracket or parenthesis? Do I have an extra one?
Did I try to use a function that isn’t defined yet or did I misspell it?
To help you out, the error messages often will list a line number of where the error is occurring, but fair warning, sometimes the line listed is NOT where the error actually occurred, which can be confusing. Our advice: start by looking at the line indicated and see if there is an error there; if not, look around that area, often before, to see if there is anything going on.
Below is a simple example that has a few bugs. Run the program, take a look at the code, and see if you can find them all! (The solution is listed after the example).
Solution: below are the errors in the program above:
On line 3, the last parenthesis before the semi-colon is missing, which results in a syntax error.
On line 8, the function tries to use the variable x
, but that variable is only local to the main()
function. This is a scope, or reference error. Replace x
with the parameter variable num
.
On line 4, the program tries to call a function, finish()
, which is not defined. This is also a reference error. You either need to define the function, or remove that line from the code.
The example above is supposed to calculate the factorial of a number, which is 6 in this case, but is always printing 0 instead. If you follow the commented steps, you’ll see that since i
started at 0, it doesn’t matter how many iterations we do, result
will always equal 0. If we change the for loop to:
then result
will equal 1 after the first iteration, 2 after the second, and 6 after the third, which is the answer we are expecting. Try it yourself above!
What follows are a handful of techniques that can be very helpful as you develop and debug your programs. Programmers will often mix and match these as they conduct their investigations.
This technique is really a best practice as you are developing any program – build it in small steps and continually test as you go. That way, when a bug pops up, you catch it earlier on and you are debugging fewer lines of code.
Before you go too deep into your investigation, if you get a syntax or reference error message, check for these three very common mistakes:
If you can’t find the mistakes, or if they are different than those above, the remaining techniques can help you narrow in on them.
This technique takes advantage of console printing and prints out variable values in order to see and confirm what they are throughout the program. For example, in the Factorial example above, we could’ve put in console.log(result)
after line 8 to see what the value of result
is after each iteration. Or we could have put in console.log("i: " + i + ", result: " + result)
before line 8 to see what the values of both i
and result
are before they are multiplied together. This would’ve helped narrow in on where the error was occurring.
This is another very effective technique to help isolate where the bug is hiding. The idea is that by commenting out code (making it not executable), you limit what code is being run, focusing your investigation. You can either comment out line by line until the error goes away, or you can comment a large chunk of code out and slowly uncomment code to see when the error appears.
This technique is similar to The Comment Technique – simplify your program (or parts of your program) to its basic functionality and see if that fixes the problem. If not, then at least you have less code to search for that bug; if it does fix the issue, then you can rebuild from there. You can either comment out code to simplify, which makes it easy to bring it back, or write the simpler version on its own.
Sometimes you just can’t find the bug no matter how long you stare at your code. The quickest approach could just be to start from scratch and rewrite that part of the code. Especially with syntax errors like missing brackets/parentheses or misspellings, a simple rewrite may resolve the issue.
Below is an example program with a few different errors. The program is trying to convert $50 US dollars to Icelandic Króna. Can you find and fix all of the bugs, so that the end result is an output of “Converted money = 6850“?
Sometimes you may not understand what is causing the syntax or logic related error. You may need to learn more about a particular topic to discover what the nature of your mistake is. Below are a few ideas that are helpful to any level of programmer:
When working in the CodeHS editor, there is a Docs tab that provides simple explanations of topics and examples of the proper syntax.
CodeHS has a handful of tutorials here for a variety of languages and topics. These tutorials break down the concepts and provide runnable examples to support the explanations.
If working on a CodeHS exercise in a course, take a look back at previous videos or examples. There is even a Video tab in the editor that allows you to quickly look through the lesson slides.
A quick Google search related to the topic and language, like “for loops in JavaScript,” will bring up a few other popular webpages that do a great job explaining the topic and its syntax. Being able to read through programming documentation is also an important skill!