Before writing more complex code, letâs talk about debugging.
Debugging is the process of finding and fixing errors within a script. All modern browsers and most other environments support debugging tools â a special UI in developer tools that makes debugging much easier. It also allows to trace the code step by step to see what exactly is going on.
Weâll be using Chrome here, because it has enough features, most other browsers have a similar process.
The âSourcesâ panel
Your Chrome version may look a little bit different, but it still should be obvious whatâs there.
- Open the example page in Chrome.
- Turn on developer tools with F12 (Mac: Cmd+Opt+I).
- Select the
Sourcespanel.
Hereâs what you should see if you are doing it for the first time:
The toggler button opens the tab with files.
Letâs click it and select hello.js in the tree view. Hereâs what should show up:
The Sources panel has 3 parts:
- The File Navigator pane lists HTML, JavaScript, CSS and other files, including images that are attached to the page. Chrome extensions may appear here too.
- The Code Editor pane shows the source code.
- The JavaScript Debugging pane is for debugging, weâll explore it soon.
Now you could click the same toggler again to hide the resources list and give the code some space.
Console
If we press Esc, then a console opens below. We can type commands there and press Enter to execute.
After a statement is executed, its result is shown below.
For example, here 1+2 results in 3, while the function call hello("debugger") returns nothing, so the result is undefined:
Breakpoints
Letâs examine whatâs going on within the code of the example page. In hello.js, click at line number 4. Yes, right on the 4 digit, not on the code.
Congratulations! Youâve set a breakpoint. Please also click on the number for line 8.
It should look like this (blue is where you should click):
A breakpoint is a point of code where the debugger will automatically pause the JavaScript execution.
While the code is paused, we can examine current variables, execute commands in the console etc. In other words, we can debug it.
We can always find a list of breakpoints in the right panel. Thatâs useful when we have many breakpoints in various files. It allows us to:
- Quickly jump to the breakpoint in the code (by clicking on it in the right panel).
- Temporarily disable the breakpoint by unchecking it.
- Remove the breakpoint by right-clicking and selecting Remove.
- â¦And so on.
Right click on the line number allows to create a conditional breakpoint. It only triggers when the given expression, that you should provide when you create it, is truthy.
Thatâs handy when we need to stop only for a certain variable value or for certain function parameters.
The command âdebuggerâ
We can also pause the code by using the debugger command in it, like this:
function hello(name) {
let phrase = `Hello, ${name}!`;
debugger; // <-- the debugger stops here
say(phrase);
}
Such command works only when the development tools are open, otherwise the browser ignores it.
Pause and look around
In our example, hello() is called during the page load, so the easiest way to activate the debugger (after weâve set the breakpoints) is to reload the page. So letâs press F5 (Windows, Linux) or Cmd+R (Mac).
As the breakpoint is set, the execution pauses at the 4th line:
Please open the informational dropdowns to the right (labeled with arrows). They allow you to examine the current code state:
-
Watchâ shows current values for any expressions.You can click the plus
+and input an expression. The debugger will show its value, automatically recalculating it in the process of execution. -
Call Stackâ shows the nested calls chain.At the current moment the debugger is inside
hello()call, called by a script inindex.html(no function there, so itâs called âanonymousâ).If you click on a stack item (e.g. âanonymousâ), the debugger jumps to the corresponding code, and all its variables can be examined as well.
-
Scopeâ current variables.Localshows local function variables. You can also see their values highlighted right over the source.Globalhas global variables (out of any functions).Thereâs also
thiskeyword there that we didnât study yet, but weâll do that soon.
Tracing the execution
Now itâs time to trace the script.
There are buttons for it at the top of the right panel. Letâs engage them.
- â âResumeâ: continue the execution, hotkey F8.
-
Resumes the execution. If there are no additional breakpoints, then the execution just continues and the debugger loses control.
Hereâs what we can see after a click on it:
The execution has resumed, reached another breakpoint inside
say()and paused there. Take a look at the âCall Stackâ at the right. It has increased by one more call. Weâre insidesay()now. - â âStepâ: run the next command, hotkey F9.
-
Run the next statement. If we click it now,
alertwill be shown.Clicking this again and again will step through all script statements one by one.
- â âStep overâ: run the next command, but donât go into a function, hotkey F10.
-
Similar to the previous âStepâ command, but behaves differently if the next statement is a function call (not a built-in, like
alert, but a function of our own).If we compare them, the âStepâ command goes into a nested function call and pauses the execution at its first line, while âStep overâ executes the nested function call invisibly to us, skipping the function internals.
The execution is then paused immediately after that function call.
Thatâs good if weâre not interested to see what happens inside the function call.
- â âStep intoâ, hotkey F11.
-
Thatâs similar to âStepâ, but behaves differently in case of asynchronous function calls. If youâre only starting to learn JavaScript, then you can ignore the difference, as we donât have asynchronous calls yet.
For the future, just note that âStepâ command ignores async actions, such as
setTimeout(scheduled function call), that execute later. The âStep intoâ goes into their code, waiting for them if necessary. See DevTools manual for more details. - â âStep outâ: continue the execution till the end of the current function, hotkey Shift+F11.
-
Continue the execution and stop it at the very last line of the current function. Thatâs handy when we accidentally entered a nested call using , but it does not interest us, and we want to continue to its end as soon as possible.
- â enable/disable all breakpoints.
-
That button does not move the execution. Just a mass on/off for breakpoints.
- â enable/disable automatic pause in case of an error.
-
When enabled, if the developer tools is open, an error during the script execution automatically pauses it. Then we can analyze variables in the debugger to see what went wrong. So if our script dies with an error, we can open debugger, enable this option and reload the page to see where it dies and whatâs the context at that moment.
Right click on a line of code opens the context menu with a great option called âContinue to hereâ.
Thatâs handy when we want to move multiple steps forward to the line, but weâre too lazy to set a breakpoint.
Logging
To output something to console from our code, thereâs console.log function.
For instance, this outputs values from 0 to 4 to console:
// open console to see
for (let i = 0; i < 5; i++) {
console.log("value,", i);
}
Regular users donât see that output, it is in the console. To see it, either open the Console panel of developer tools or press Esc while in another panel: that opens the console at the bottom.
If we have enough logging in our code, then we can see whatâs going on from the records, without the debugger.
Summary
As we can see, there are three main ways to pause a script:
- A breakpoint.
- The
debuggerstatements. - An error (if dev tools are open and the button is âonâ).
When paused, we can debug: examine variables and trace the code to see where the execution goes wrong.
There are many more options in developer tools than covered here. The full manual is at https://developers.google.com/web/tools/chrome-devtools.
The information from this chapter is enough to begin debugging, but later, especially if you do a lot of browser stuff, please go there and look through more advanced capabilities of developer tools.
Oh, and also you can click at various places of dev tools and just see whatâs showing up. Thatâs probably the fastest route to learn dev tools. Donât forget about the right click and context menus!
Comments
<code>tag, for several lines â wrap them in<pre>tag, for more than 10 lines â use a sandbox (plnkr, jsbin, codepenâ¦)