For other translations of this series, see [JS Working Mechanism – Xiaobai’s 1991 column – Nuggets (juejin. Cn)] (juejin.cn/column/6988…

Both are basic debugging methods, not very high value

Debugging is an important part of software development, and any developer can improve in this area. Leaving significant bugs in your release environment can be costly to your application and your company. Debugging includes finding and fixing bugs. During debugging, you can step through code to determine where exceptions occur and what is causing them. All modern browsers have JS reminders built in. JS also has some internal methods and tags, easy to debug. Debugging synchronous and asynchronous code in JS is slightly different. Because, in asynchrony, functions are called and returned out of order. Timeouts are also a bug if there is no response within the specified time. In this chapter, we’ll discuss debugging in JS, as well as tips for debugging asynchronous code.

Why is debugging important

Debugging avoids most incorrect behavior in your application by finding bugs and incorrect code. Bugs often crash your application. With proper debugging, you can find problems in your code and avoid some of them. For example, using debugging you can determine the cause of runtime or compile-time errors. Some code may not throw an exception or an error, but it may realize an exception. For example, specifying incorrect variables causes unexpected behavior.

let a = 5; let b = 10; let c = 12; let d = a + b; // Developer was meaning to write let e = a + c; let e = b + c;Copy the code

In the code above, the developer expected 17, but got a 22. If developers debug code using console.log(), they can track exceptions on the console. Sometimes developers use tools and programs to create applications. With proper debugging, developers can determine the overall performance of their applications.

How to debug JS applications

Most Web applications use JS, and mobile applications are increasingly using JS. Before pushing their release environments, developers need to debug them.

Sometimes developers need to be more careful than just writing code. Take a look at the debugging process of a debugging JS application:

Locate the Bug

The first step in debugging is to locate the bug. Engineers can find bugs when exceptions occur or simply check the code.

Debugging is either active or passive. Passive debugging, where the developer takes control of the debugging steps. In other words, developers can collect logs and valid data from execution steps.

However, there are some scenarios where developers need to communicate with the application during debugging. For example, a developer may need to send data to an application in order to debug its behavior. This scenario cannot be satisfied with passive debugging, which involves only executing debugging steps and printing data from the debugger. Therefore, developers use an active approach to debugging. Active debugging allows developers to communicate with applications

The separation of the bug

The process of separating bugs is to determine which part of the program is causing the exception. In this step, the developer tries to separate the part of the code that causes the exception from the application so that it can be debugged more thoroughly. This step generally includes these methods:

1. Forward analysis

In this way, developers debug the code separately, sometimes placing breakpoints. Once an exception is recorded, the developer focuses on that area to determine the cause of the exception.

2. Reverse analysis

Sometimes, developers need to trace exceptions backwards, from the current breakpoint to the previous breakpoint to find the cause of the exception. That’s the reverse analysis

Determine the cause of the bug

Once the bug is isolated, it’s time to debug the isolated parts to determine the cause. For example, if the exception revolves around an incorrect input field, all the input fields are debugged to determine the cause of the bug.

Fix the Bug

Once the cause of the Bug is determined, the next step is to fix it. If it turns out to be a deeper problem, related to application architecture, more experienced developers need to deal with it

The test application

Debugging is an iterative process, from development to launch. After fixing bugs, developers continue testing to see if there are any other problems. Sometimes, fixing bugs creates more bugs.

JS test methods

In this section, we’ll discuss some ways to debug JS:

Web console

Most browsers come with a console that allows developers to record information about the page. One advantage of the console is that you can execute JS expressions on it. Let’s take a look at some console-related debugging methods. Suppose we debug this code like this:

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, <title>Debugging Test</title> </head> <body> <p id="demo">Click the button to display greeting.</p> <button onclick="myFunction()">Display Greeting</button> <script> function myFunction() { document.getElementById("demo").innerHTML = "Hello World"; } </script> </body> </html>Copy the code
  1. The log

For quick debugging, use the console.log() method. In our example, we want to make sure that the button works by making sure that the id of the call is correct. We can log a message when the id of our call is different from the ID of the button.

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, <title>Debugging Test</title> </head> <body> <p id="demo">Click the button to display greeting.</p> <button onclick="myFunction()">Display Greeting</button> <script> function myFunction() { let id = document.getElementById("demo").id; let correctId = "demo"; if (id === correctId) { document.getElementById("demo").innerHTML = "Hello World"; }else console.log ("ID doesn't match, id is", id.id) } </script> </body> </html>Copy the code

We won’t get any logs here, because the “demo” ID we called is the same as the id of the button. If the developer specified the button ID as “demi”, it can specify DemI to correctId.

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, <title>Debugging Test</title> </head> <body> <p id="demo">Click the button to display greeting.</p> <button onclick="myFunction()">Display Greeting</button> <script> function myFunction() { let id = document.getElementById("demo").id; let correctId = "demi"; if (id === correctId) { document.getElementById("demo").innerHTML = "Hello World"; } else console.log("ID doesn't match, id is", id); } </script> </body> </html>Copy the code

Now, we have a log,ID doesn’t match, id is demo. Using this information, the developer knows that they assigned the button incorrectlyid 2. The warning

Sometimes there are so many logs in the console that it is difficult to locate problems quickly. To make important information stand out, use the console.warn() method. This is similar to console.log(), but it prints the log as a warning.

In the same example, we use console.warn() instead of console.log()

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, <title>Debugging Test</title> </head> <body> <p id="demo">Click the button to display greeting.</p> <button onclick="myFunction()">Display Greeting</button> <script> function myFunction() { let id = document.getElementById("demo").id; let correctId = "demi"; if (id === correctId) { document.getElementById("demo").innerHTML = "Hello World"; } else console.warn("ID doesn't match, id is", id); } </script> </body> </html>Copy the code

3. Error

Sometimes, exception logs are easier to notice. We can do this using the console.error() method. Again, use console.error() to change the example above:

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, <title>Debugging Test</title> </head> <body> <p id="demo">Click the button to display greeting.</p> <button onclick="myFunction()">Display Greeting</button> <script> function myFunction() { let id = document.getElementById("demo").id; let correctId = "demi"; if (id === correctId) { document.getElementById("demo").innerHTML = "Hello World"; } else console.error("ID doesn't match, id is", id); } </script> </body> </html>Copy the code

4. The assertionIf the assertion fails,console.assert()An exception will be written to the console. Also, modify our example:

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, <title>Debugging Test</title> </head> <body> <p id="demo">Click the button to display greeting.</p> <button onclick="myFunction()">Display Greeting</button> <script> function myFunction() { let id = document.getElementById("demo").id; let correctId = "demi"; const errorMsg = "the ID doesn't match the correct ID"; console.assert(id === correctId, { errorMsg: errorMsg }); if (id === correctId) { document.getElementById("demo").innerHTML = "Hello World"; } } </script> </body> </html>Copy the code

5. The Debugger statement

The debugger is used to trigger a debbugger or to suspend the execution of code. It is used to set breakpoints for your application. Breakpoints are great for debugging because they allow the developer to probe the application while it is executing.

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, <title>Debugging Test</title> </head> <body> <p id="demo">Click the button to display greeting.</p> <button onclick="myFunction()">Display Greeting</button> <script> function myFunction() { let id = document.getElementById("demo").id; let correctId = "demi"; debugger; document.getElementById("demo").innerHTML = "Hello World"; } </script> </body> </html>Copy the code

Use the debugger to debug JS

Debugging tools are also debuggers that provide enhanced visualization and analysis to help developers quickly locate and fix bugs. Let’s take a look at the Firefox debugger:

Firefox JS Debugger

Firefox JS debugger, which allows you to debug your JS applications locally and remotely. You can set breakpoints, events, debug threads, etc.

Start debugging

Start your debugger by pressing CTRL + SHIFT + I, then switch to the Debugger panel. Notice that the debugger is divided into three sections. The first section contains the required files for the page, the second section contains the files of interest to the developer (that is, the files you want to debug), and the third section contains the tools you need to debug.

To open our file, click on the first panelfile://Folder, then select the files you are related to,

suspended

Breakpoints pause code execution during debugging, and in this section we’ll look at the different types of breakpoints

Unconditional breakpoint

In this section we use the console.error() example. When you click on the line number of the file, a breakpoint is added, which is an unconditional breakpoint. You can also use the right-click menu to Add Breakpoint

We add an unconditional breakpoint at line 16, and if (id === correctId) you get a message saying “Paused at execution”

Now you can step through your code. During debugging, there may be some unexpected logs. For example, in line 19, you will get the exception message. Note that you cannot add breakpoints in your HTML code.

Conditional breakpoints

Your breakpoint will only work if the expression you define is true. This is called a conditional breakpoint. For example, in line 16: if (id === correctId) {add the following condition that will not cause an interrupt because the ID is inconsistent with correctId

id ! = correctIdCopy the code

If we changeid === correctIdThe interrupt will not be triggered.

Event listening breakpoint

Developers can also add event listeners to breakpoints or exception pauses. In the third panel, open the Event Listener Breakpoints option and click on any Event Listener of your choice.

If you want to Pause the program whenever Exceptions occur, select “Pause on Exceptions”.

Step through

While the code is paused, you can step through it and observe exceptions. You can step over, step in, or step out. Step over executes the next line of code in the function, but does not enter the child function. Step in enters when it encounters a subfunction. Step OUT completes the current function

Tips for debugging asynchronous code

Asynchronous debugging is a little different from synchronous debugging. Asynchronous code runs after the main thread and does not block the execution of JS code. During this process, an exception occurs if there is a timeout or no response.

When debugging asynchronous JS code, keep these tips in mind:

  1. A timeout exception occurred, either due to code or network connection. Start by promoting timeout events and checking network connections.
  2. Asynchronous code data is not sequential, select the “Pause on Exception” button when debugging. Execution is paused when you get an exception. Use step over to explore the entire call stack.
  3. The first step in asynchronous debugging is to use it in different snippets of codeconsole.log()methods
  4. usetry 和 catchDeclaration to handle exceptions