while (test) {...} checks before each pass and do {...} while (test) after it, so its body runs at least once. for (init; test; update) {...} runs its parts in the order shown below. for (key in object) visits enumerable property names as strings (added and inherited ones too); for (value of iterable) visits the values of arrays, strings, Maps, Sets and generators (Iterables and Iterators). break leaves a loop, continue skips to the next pass, and a label aims either at an outer loop.

const arr = [3, 5, 7];
arr.foo = "hello";
const seen = [];
for (const k in arr) seen.push(k); // names as strings, extras too
for (const v of arr) seen.push(v); // values from the iterator
let i = 0;
do { i += 5; } while (i < 3); // body runs at least once
outer: for (let a = 1; a < 10; a++) {
for (let b = 1; b < 10; b++) if (a * b > 50) { seen.push(`${a}*${b}`); break outer; }
}
console.log(seen.join(" "), i);0 1 2 foo 3 5 7 6*9 5
Plain objects are not iterable, so loop over Object.entries(obj) (Object Static Methods). Unlike for...of, forEach() cannot break.