Warm-up · Activity 1 of 7
// B3.4 · ~30 min · Beginner
break and continue
After this lesson you stop a loop at the first match, skip bad entries without stopping, and know where break and continue are allowed.
You will be able to
- Stop a loop at the first match with break, and know that break in a switch leaves only the switch
- Skip invalid entries with continue, and keep it from skipping the update of a while loop
- Read a labelled break, and fix the SyntaxErrors of a break or continue in the wrong place
Predict · Activity 2 of 7
Predict before you read on: what does this print?
for (let i = 1; i <= 5; i++) { if (i === 3) { continue; } console.log(i); }Practice · Activity 3 of 7
Fill in the keyword so that the program prints the first temperature above 30, which is 31, and stops looking.
const temps = [12, 18, 31, 25, 33]; let firstHot; for (const t of temps) { if (t > 30) { firstHot = t; ____; } } console.log(firstHot);;Practice · Activity 4 of 7
A switch inside a loop. What does this print?
const commands = ["go", "stop", "go"]; for (const c of commands) { switch (c) { case "stop": console.log("stopping"); break; default: console.log("going"); } }Practice · Activity 5 of 7
Each line goes first in the block of for (const n of [1, 2, 3, 4]) { … console.log(n); }. Match it to the numbers the loop prints.
Brain teaser · Activity 6 of 7
Brain teaser. Do not run this one. What happens?
let i = 0; while (i < 5) { if (i === 2) { continue; } console.log(i); i++; }Apply · Activity 7 of 7
Mini-task. Write a step counter log. Put daily step counts in an array, with some bad entries such as "n/a" or -1. Loop over the days with a counting for loop: print Day 2: no data for a bad entry and skip it with continue, print Day 1: 5200 steps for a good one, and stop with break on the first day that reaches a goal of 10000. Last, print Goal reached on day 5 (or Goal not reached).
Check your work against this list
Build it yourself
Read the worked example, then write the exercises. Your code runs in your browser or on your computer and is never uploaded.
Worked example
Scan a thermometer log
A thermometer logged eight readings, but two are bad: a text "error" and the value -999, which the device writes when it fails. The program skips the bad ones with continue, adds up the good ones, and stops with break at the first reading above 30, the alarm. Run it, then change 31.5 to 29 and predict the output before you run it again.
main.js
// Scan the readings of a thermometer.
const readings = [21.5, 22, "error", 23.5, -999, 24, 31.5, 25];
let total = 0;
let count = 0;
let firstAlarm;
for (const r of readings) {
if (typeof r !== "number" || r < -50) {
console.log("skip:", r);
continue;
}
total += r;
count++;
if (r > 30) {
firstAlarm = r;
break;
}
}
console.log("used", count, "readings");
console.log("average", (total / count).toFixed(1));
console.log("first alarm:", firstAlarm);
Run it with
node main.jsOutput
skip: error
skip: -999
used 5 readings
average 24.5
first alarm: 31.5- continue skips the bad readings: they are printed, but never added or counted.
- break ends the loop at 31.5, so the last reading, 25, is never used.
- The average is worked out after the loop, from the readings that were used: 122.5 / 5.
- With no reading above 30, the loop runs to the end and firstAlarm stays undefined.
Change it and run it
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the JavaScript runner (up to 0.1 MB) and keeps it cached. Your code runs in your browser’s own engine and stays on your device.
Exercises
Exercise 1 of 2
Stop at the first match
The program should report the first price above the budget and stop looking, but it reports the last one and checks every price. Make it print First price above 10: 12 at position 1 and then Checked 2 prices. Keep the counter checked++ as the first line of the loop.
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the JavaScript runner (up to 0.1 MB) and keeps it cached. Your code runs in your browser’s own engine and stays on your device.
Hints
Hint 1
Run the starter: it reports 25, because every later match overwrites found.
Hint 2
Once found and position are set, nothing more needs checking. Which keyword ends the loop at once?
Hint 3
Add break; as the last line inside the if.
Show a solution
One way to solve it. Yours can look different and still pass the checks.
const prices = [4.5, 12, 7.25, 19.99, 3, 25];
const budget = 10;
let found;
let position;
let checked = 0;
for (let i = 0; i < prices.length; i++) {
checked++;
if (prices[i] > budget) {
found = prices[i];
position = i;
break;
}
}
console.log(`First price above ${budget}: ${found} at position ${position}`);
console.log(`Checked ${checked} prices`);
Run it on your computer
Install ECMAScript 2026 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.
main.js
const prices = [4.5, 12, 7.25, 19.99, 3, 25];
const budget = 10;
let found;
let position;
let checked = 0;
for (let i = 0; i < prices.length; i++) {
checked++;
if (prices[i] > budget) {
found = prices[i];
position = i;
}
}
console.log(`First price above ${budget}: ${found} at position ${position}`);
console.log(`Checked ${checked} prices`);
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';
const lines = async () => (await runMain()).trimEnd().split('\n');
test('reports the first price above the budget', async () => {
const got = await lines();
assert.equal(got[0], 'First price above 10: 12 at position 1', `the first line is ${JSON.stringify(got[0])}, expected "First price above 10: 12 at position 1"`);
});
test('stops looking after the match', async () => {
const got = await lines();
assert.equal(got[1], 'Checked 2 prices', `the second line is ${JSON.stringify(got[1])}, expected "Checked 2 prices"`);
});
test('prints exactly two lines', async () => {
const got = await lines();
assert.equal(got.length, 2, `the program printed ${got.length} line(s), expected 2`);
});
package.json
{
"type": "module"
}
package.json tells Node.js that the .js files are modules; keep it in the folder.
Run the program:
node main.jsRun the checks (needs learnrun.js in the same folder):
node --testDownload learnrun.jsExercise 2 of 2
Skip the bad entries
An order form sent these quantities, and some are not usable. Skip every entry that is not a number or is not above 0: print Skipped: two (with the entry) and go on with the next one using continue. Add up the others and count them, and print Total: 12 from 3 entries at the end.
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the JavaScript runner (up to 0.1 MB) and keeps it cached. Your code runs in your browser’s own engine and stays on your device.
Hints
Hint 1
Run the starter: "two" turns the total into text, and 0 and -1 are counted too.
Hint 2
A bad entry is one where typeof q !== "number" || q <= 0. Test that first in the loop.
Hint 3
Inside that if, print the line, then write continue; so that the adding below is skipped for this entry.
Show a solution
One way to solve it. Yours can look different and still pass the checks.
const quantities = [3, "two", 0, 5, -1, 4];
let total = 0;
let used = 0;
for (const q of quantities) {
if (typeof q !== "number" || q <= 0) {
console.log(`Skipped: ${q}`);
continue;
}
total += q;
used++;
}
console.log(`Total: ${total} from ${used} entries`);
Run it on your computer
Install ECMAScript 2026 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.
main.js
const quantities = [3, "two", 0, 5, -1, 4];
let total = 0;
let used = 0;
for (const q of quantities) {
// Skip anything that is not a number above 0.
total += q;
used++;
}
console.log(`Total: ${total} from ${used} entries`);
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';
const lines = async () => (await runMain()).trimEnd().split('\n');
test('reports each bad entry', async () => {
const got = await lines();
assert.deepEqual(got.slice(0, 3), ['Skipped: two', 'Skipped: 0', 'Skipped: -1'], `the first three lines are ${JSON.stringify(got.slice(0, 3))}`);
});
test('adds up only the good entries', async () => {
const got = await lines();
assert.equal(got[got.length - 1], 'Total: 12 from 3 entries', `the last line is ${JSON.stringify(got[got.length - 1])}, expected "Total: 12 from 3 entries"`);
});
test('prints exactly four lines', async () => {
const got = await lines();
assert.equal(got.length, 4, `the program printed ${got.length} line(s), expected 4`);
});
package.json
{
"type": "module"
}
package.json tells Node.js that the .js files are modules; keep it in the folder.
Run the program:
node main.jsRun the checks (needs learnrun.js in the same folder):
node --testDownload learnrun.jsCommon mistakes
break to leave an if
const score = 120;
if (score > 100) {
console.log("too high");
break;
}
console.log("score", score);
What Node.js prints
SyntaxError: Illegal break statementWhy, and the fix
break ends a loop or a switch, and an if is neither. Outside a loop or switch the file cannot be read, so not even the first line runs. To leave an if early, put the rest of the work in an else, or turn the test round: if (score <= 100) { … }.
continue in a switch that is not in a loop
const day = "sun";
switch (day) {
case "sun":
console.log("closed");
continue;
default:
console.log("open");
}
What Node.js prints
SyntaxError: Illegal continue statement: no surrounding iteration statementWhy, and the fix
continue means "go on with the next pass of the loop", and here there is no loop around the switch, only the switch. A case ends with break, not continue. Inside a loop, continue in a case is allowed and goes on with the loop’s next pass.
A misspelled label
outer: for (const row of [1, 2]) {
for (const col of [1, 2]) {
if (row === col) {
break outr;
}
console.log(row, col);
}
}
What Node.js prints
SyntaxError: Undefined label 'outr'Why, and the fix
A label works only if break or continue names it exactly and stands inside the statement it labels. outr is not outer, so JavaScript finds no such label around the break, and the whole file cannot be read. Write break outer;, or use a plain break if leaving the inner loop is enough.
JavaScript in the browser: your browser’s own engine, in a sandboxed worker. Syntax errors are located with acorn 8.18.0, MIT. Licence and source
Exit ticket
5 questions, no hints. Score 80% or more to complete the lesson.
Finish every activity above to unlock the exit ticket.