This episode covers how a program makes decisions and repeats work: branching with if, else if, and switch, plus loops with for, while, do...while, and for...of. You also learn break, continue, and modern loop patterns.

After episode 2, you can store values and process them. But a program is useless if it only runs straight from top to bottom. Control flow gives a program the ability to make decisions and repeat work — two behaviors that make code feel alive.
Episode 3 covers two sides of control flow. The first side is branching: if, else if, else, and switch for choosing which path to take. The second side is loops: for, while, do...while, and for...of for executing code repeatedly.
All examples can be run directly with node. Try changing the input values in each example and observe how the output changes — that's the best way to understand branching and loop behavior.
if executes a block of code only when the condition is truthy:
const nilai = 85;
if (nilai >= 90) {
console.log("Nilai A");
} else if (nilai >= 75) {
console.log("Nilai B");
} else {
console.log("Nilai C");
}Conditions are evaluated in order from the top. If nilai >= 90 is false, only then is nilai >= 75 tested; if all are false, the else block runs. For nilai = 85, the output is Nilai B. if (nilai >= 90) is the most common form of branching in JavaScript.
For a simple two-branch decision, use the ternary operator:
const umur = 20;
const status = umur >= 17 ? "Bisa buat SIM" : "Belum bisa";
console.log(status);The ternary structure is kondisi ? nilaiBenar : nilaiSalah. For umur = 20, the result is "Bisa buat SIM". Ternary keeps code concise, but don't use it for nested conditions — the readability gets confusing.
When a single value is compared against many possibilities, switch is tidier than a chain of else if:
const hari = "selasa";
let pesan;
switch (hari) {
case "senin":
pesan = "Mulai minggu dengan semangat";
break;
case "selasa":
pesan = "Saatnya fokus";
break;
case "jumat":
pesan = "Akhir pekan hampir tiba";
break;
default:
pesan = "Hari biasa";
}
console.log(pesan);switch (hari) compares the value with each case using strict comparison. The break keyword stops execution; if omitted, execution will fall through to the next case. The default block handles values that match nothing — the equivalent of else.
for repeats code with an explicit counter. Its structure has three parts: initialization, condition, and increment:
for (let i = 1; i <= 5; i++) {
console.log(`Iterasi ke-${i}`);
}for (let i = 1; i <= 5; i++) starts i at 1, loops while i <= 5, and increments i each iteration. The output is five lines from Iterasi ke-1 to Iterasi ke-5. The variable i is declared with let because its value changes.
while loops as long as the condition stays true, checking the condition at the start:
let sisa = 10;
while (sisa > 0) {
console.log(`Sisa: ${sisa}`);
sisa -= 3;
}
let berapa = 0;
do {
console.log("Jalan minimal sekali");
berapa++;
} while (berapa < 3);while (sisa > 0) may not run at all if the condition is already false at the start. In contrast, do...while always runs at least once because the condition is checked after the block. Choose do...while when you're sure the block must run at least once.
for...of loops over the values of arrays, strings, Sets, and other iterable objects. This is the loop used most often in modern JavaScript:
const buah = ["apel", "pisang", "mangga"];
for (const item of buah) {
console.log(item.toUpperCase());
}
for (const huruf of "JS") {
console.log(huruf);
}for (const item of buah) grabs each array element directly — no index needed and no risk of miscounting the array length. This loop is safer and easier to read than the classic for.
for...in loops over the property names of an object. The difference from for...of is essential to remember: for...of gives values, for...in gives key names:
const pengguna = { nama: "Arman", role: "Engineer" };
for (const kunci in pengguna) {
console.log(`${kunci}: ${pengguna[kunci]}`);
}The output is nama: Arman and role: Engineer. An important note: don't use for...in on arrays — the order isn't guaranteed. For arrays, always use for...of, and we'll dig deeper into objects in episode 5.
The break keyword stops a loop entirely, while continue jumps to the next iteration:
const angka = [3, 8, 15, 22, 30];
for (const nilai of angka) {
if (nilai % 2 === 0) continue;
if (nilai > 20) break;
console.log(nilai);
}For the list [3, 8, 15, 22, 30]: 3 is printed (odd), 8 is skipped by continue (even), 15 is printed, and 22 stops the loop via break before being printed. if (nilai > 20) break is a common pattern for stopping early for efficiency.
Tip
Choose a loop with intention: for...of for arrays, for...in for object keys, while for dynamic conditions where you don't yet know the number of iterations, and the classic for when you genuinely need an index. Don't rewrite arrays with while — that's a source of confusing index bugs.
Episode 3 completed the control flow foundation: if, else if, else, and ternary for branching, switch for many cases, for, while, and do...while for loops, and for...of and for...in as modern loops. You also learned break and continue to steer a loop's journey.
Key takeaways:
if and else execute blocks based on a truthy condition.kondisi ? a : b for simple two-branch decisions.switch fits comparing one value against many cases.for...of loops over array and iterable values; for...in loops over object keys.while checks the condition first; do...while always runs at least once.break stops a loop, continue jumps to the next iteration.In the next episode 4 we'll cover functions and variable scope — how to wrap logic into reusable callable blocks, understand parameters and return values, and distinguish global, function, and block scope. This is where your code starts to become well organized.