Logging shows you what happened after the fact. A breakpoint pauses your code while it runs, on the exact line you choose, so you can look at every variable, then step forward one line at a time and watch values change. You do not guess values with breakpoints; you see them.
Breakpoints are set in the browser's developer tools, not in your code:
W3Schools' practice code calls a function four times. Put a breakpoint on the let result line and watch a, b, and result on each call:
function add(a, b) {
let result = a + b;
return result;
}
console.log(add(10, 5));
console.log(add(10, 50));
console.log(add(10, 500));
console.log(add(10, 5000));
(W3Schools shows each result on the page with document.getElementById("demo").innerHTML = ..., which finds the element with id "demo" and replaces its content. console.log is simpler for practice.)
Writing debugger; in your code works like a breakpoint on that line, but only while the developer tools are open. When they are closed, it does nothing:
let x = 15 * 5;
debugger; // pauses here if the developer tools are open
console.log(x);
debugger statement when you are done. Left in, it will pause the page for anyone who happens to have their developer tools open.
While paused, a row of buttons (and keyboard shortcuts) controls what runs next:
| Button | Chrome key | What it does |
|---|---|---|
| Resume | F8 | Run normally until the next breakpoint |
| Step over | F10 | Run the current line, including any function it calls, and stop on the next line |
| Step into | F11 | If the line calls a function, go inside it and stop on its first line |
| Step out | Shift+F11 | Finish the current function and stop where it was called |
Step slowly and watch how the values change. Hovering over a variable in the code also shows its current value.
While paused, the Scope panel lists every variable available at the current line, grouped the way JS Scope describes them: Local (inside the current function), Block (inside the current { }), Closure (from an outer function), and Global.
let x = 10;
function test() {
let y = 5;
console.log(x + y); // pause here: y is Local, x is under Script/Global
}
test();
Add a variable name or any expression (like total / count or items.length) to the Watch panel, and its value updates every time you step. It is a cleaner alternative to adding many console.log calls.
The Call Stack shows how you got to the current line: which function called which. Click any entry to jump to that spot and see the variables there. It is the same chain the stack property of an error shows (JS Error Object).
A breakpoint inside a loop stops on every repetition. Right-click the line number instead:
i === 7, and it only pauses when that is true."i is", i, and it logs to the console without pausing and without editing your code.let total = 0;
for (let i = 1; i <= 10; i++) {
total += i * i; // try a conditional breakpoint: i === 7
}
console.log(total);
debugger; statements in finished code.| Tool | Best for |
|---|---|
| console.log | A quick look at one or two values |
| Breakpoint | Values change unexpectedly, or you need to see many variables at once |
| Conditional breakpoint | A bug that only happens on one repetition of a loop |
| Logpoint | Logging without editing (or later cleaning up) your code |
The code is paused on a line that calls calculate(). Which button takes you inside calculate?
What does this log when the developer tools are closed?
let n = 2;
debugger;
n = n * 21;
console.log(n);
42. With the tools closed, debugger does nothing, and the code runs straight through.A bug only happens when i is 500 in a loop that runs 1000 times. How do you pause at exactly that point?
i === 500. It will only pause when that is true.debugger linea, b, and result in the Scope paneldebugger; inside the loop, and add total to the Watch paneli === 7