
코딩을 하다 보면 같은 짓을 수도 없이 반복해야 할 때가 생긴다. 그때마다 코드 복붙으로 줄 세우는 건 손목을 갈아버리는 자해 행위일 뿐 아니라, 나중에 고치려 들면 유지보수 지옥에서 두들겨 맞는 꼴이 된다.
여기서 등장하는 것이 반복문(loop)이다. 반복문은 “동쪽으로 다섯 걸음 가라” 같은 구체적인 지시를 기계적으로 실행해주는 도구다. 한 번 조건을 정해두면, 컴퓨터는 그 조건이 바뀔 때까지 똑같은 일을 수행한다.
JavaScript는 여러 종류의 반복 구문을 제공하며, 각 구문은 어디서 시작할지, 언제 멈출지, 어떤 식으로 건너뛸지를 다르게 선택할 수 있다. 상황에 따라 적절한 반복문을 고르면 코드가 훨씬 깔끔하고 직관적으로 바뀐다.
정해진 초기화 → 조건 검사 → 후처리 흐름을 갖는 대표적인 반복문이다.
for (let step = 0; step < 5; step++) {
console.log("Walking east one step"); // 5회 실행 (0 ~ 4)
}
형식:
for (initialization; condition; update) {
statement
}
initialization: 루프 변수 선언/초기화condition: true인 동안 본문 실행 (생략 시 항상 true)update: 각 회차 종료 뒤 실행 👉 복수 문장을 실행할 땐 반드시 {}로 블록을 만든다.실전 예시(선택 목록 카운트):
function countSelected(selectEl) {
let count = 0;
for (let i = 0; i < selectEl.options.length; i++) {
if (selectEl.options[i].selected) count++;
}
return count;
}
본문을 최소 한 번은 실행한 뒤 조건을 검사한다.
let i = 0;
do {
i += 1;
console.log(i);
} while (i < 5);
조건이 참인 동안 계속 실행한다. 조건을 먼저 검사한다.
let n = 0;
let x = 0;
while (n < 3) {
n++;
x += n;
}
// n: 1→2→3, x: 1→3→6
주의: 종료 조건이 거짓이 될 경로가 반드시 있어야 한다.
// ❌ 무한 루프 예시
while (true) {
console.log("Hello, world!");
}
문에 이름(레이블)을 붙여 break/continue의 대상 범위를 지정할 수 있다.
outer: while (true) {
// ...
while (true) {
// ...
break outer; // 바깥 루프까지 탈출
}
}
반복문(for/while/do-while)이나 switch를 즉시 종료한다.
for (let i = 0; i < a.length; i++) {
if (a[i] === target) break; // 찾는 순간 종료
}
레이블과 함께 쓰면 지정한 레이블 문을 종료한다.
cancelAll: while (true) {
// ...
while (true) {
if (done) break cancelAll; // 가장 바깥까지 탈출
}
}
현재 회차만 건너뛰고 다음 회차로 진행한다.
let i = 0;
let sum = 0;
while (i < 5) {
i++;
if (i === 3) continue; // 3은 건너뜀
sum += i;
console.log(sum); // 1, 3, 7, 12
}
레이블과 함께 쓰면 해당 루프의 다음 회차로 이동한다.
checkI: for (let i = 0; i < 3; i++) {
checkJ: for (let j = 5; j > 0; j--) {
if (j % 2 === 0) continue checkJ; // 짝수는 건너뛰기
console.log(i, j, "is odd");
}
}
function dumpProps(obj, name) {
let out = "";
for (const k in obj) {
out += `${name}.${k} = ${obj[k]}\n`;
}
return out;
}
배열에는 권장하지 않는다. 사용자 정의 속성까지 함께 순회하기 때문이다.
const arr = [3, 5, 7];
arr.foo = "hello";
for (const k in arr) {
console.log(k); // "0", "1", "2", "foo" ← 인덱스 외 key까지 출력
}
👉 배열 요소를 순회할 땐 for(인덱스), for...of, Array.prototype.forEach를 사용한다.
Map, Set, arguments 등에서 동작한다.const arr = [3, 5, 7];
for (const v of arr) {
console.log(v); // 3, 5, 7
}
for...in과의 차이:
const arr = [3, 5, 7];
arr.foo = "hello";
for (const k in arr) console.log(k); // "0" "1" "2" "foo"
for (const v of arr) console.log(v); // 3 5 7
구조 분해와 함께 쓰면 키·값을 동시에 다룰 수 있다.
const obj = { foo: 1, bar: 2 };
for (const [k, v] of Object.entries(obj)) {
console.log(k, v); // foo 1 / bar 2
}
간단히 말해, 배열 값에는 for...of, 객체 속성에는 for...in, 정교한 제어에는 전통적 for/while을 고른다. 무한 루프와 레이블 남용만 피하면, 반복문은 코드의 반복을 가장 깔끔하게 해결해 준다.