코드 블록을 실행(조건문)하거나 반복 실행(반복문)할 때 사용한다.
제어문은 코드의 흐름을 제어할 수 있는데, 순차적으로 진행하는 코드의 흐름을 인의적으로 간섭하기 때문에 흐름에 혼란을 줘 가독성을 해치는 단점이 있다.
0개 이상의 문을 중괄호로 묶은 것으로, 코드 블록 또는 블록이라고 부른다. 제어문이나 함수 정의할 때 사용하며 자바스크립트는 블록문을 하나의 실행 단위로 취급한다.
주어진 조건식의 평가 결과에 따라 코드 블록의 실행을 결정한다. 조건식은 불리언 값으로 평가될 수 있는 표현식이다.
if...else문
주어진 조건식의 평가 결과(참/거짓)에 따라 실행할 코드블록을 결정한다. 평가 결과가 true일 경우 if문의 코드가 실행되고, false일 경우 else 문의 코드가 실행된다.
if (조건식1) {
// 참이면 코드 실행
} else if (조건식2) {
// 참이면 코드 실행
} else {
// 거짓이면 코드 실행
}
let num = 2;
let kind;
if (num > 0) kind = '양수';
else if (num < 0) kind = '음수';
else kind = '0';
// 양수
// 경우의 수 2개
let x = 2;
let result = x ? (x > 0 ? '홀수' : '짝수') : '영'; //짝수
// 경우의 수 3개
let x = 2;
let result = x % 2 ? '홀수' : '짝수'; //짝수
switch 문
switch문은 주어진 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 case문으로 실행 흐름을 옮긴다. case문은 상황을 의미하는 표현식을 지정하고 콜론으로 마친다.
switch (표현식) {
case 표현식1:
switch 문의 표현식과 표현식1이 일치하면 실행될 문;
break;
case 표현식2:
switch 문의 표현식과 표현식2이 일치하면 실행될 문;
break;
default:
switch 문의 표현식과 일치하는 case문이 없을 때 실행될 문;
}
//월을 영어로 변환하는 예제
let month = 12;
let monthName;
switch (month) {
case 1: monthName = 'January':
break;
case 2: monthName = 'February':
break;
case 3: monthName = 'March':
break;
...
case 12: monthName = 'December':
break;
default: monthName = 'Invalid month';
}
console.log(monthName); // December
if else문은 불리언 값으로 평가되는 반면, switch 문은 문자열이나 숫자인 경우가 많다. 논리적 참, 거짓보다는 다양한 상황(case)에 따라 실행할 코드 블록을 결정할 때 사용한다.
// 윤년 판별하여 2월 일수 계산하는 예제
let year = 2000; // 2000년은 윤년으로 2월이 29일이다.
let month = 2;
let days = 0;
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31;
break;
case 4: case 6: case 9: case 1:
days = 30;
break;
case 2:
// 윤년 계산 알고리즘
// 1. 연도가 4로 나눠 떨어지는 해(2000, 2004, 2008, 2012, 2016, 2020...)는 윤년
// 2. 연도가 4로 나눠 떨어져도 100으로 나눠 떨어지는 해(2000, 2100, 2200...)는 평년
// 3. 연도가 400으로 나눠 떨어지는 해(2000, 2400, 2800...)는 윤년
days = ((year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0)) ? 29 : 28;
break;
default:
console.log('Invalid month');
}
console.log(days); // 29
반복문은 조건식의 평가 결과가 참인 경우 실행한다. 그 후, 조건식을 다시 평가하여 여전히 참인 경우 코드 블록을 다시 실행한다. 이는 조건식이 거짓일 때까지 반복된다.
반복문을 대체하는 다양한 기능
forEach 메서드 - 배열 순회
for ... in 문 - 객체의 프로퍼티를 열거할 때
for ... of 문 - ES6에서 도입. 이터러블을 순회 할 때
for문은 조건식이 거짓으로 평가될 때까지 반복 실행한다. 아래는 예제 코드의 원리를 순서대로 분석한 것이다.
for (변수 선언 or 할당; 조건식; 증감식){
조건식이 참인 경우 반복 실행될 문;
}
for (let i = 0; i < 2; i++){
console.log(i);
} // 0 1
// 0에서 초기화 된 상태에 시작해서 i가 2보다 작을 때까지 코드를 2번 반복 실행한다.
for문의 변수 선언문, 조건식, 증감식은 모두 옵션이므로 반드시 사용할 필요가 없다. 하지만 어떤 식도 선언하지 않으면 무한루프가 된다.
for (;;) {...}
for문 내에 for문을 중첩으로 사용할 수 있다.
ex)중첩문
// 두개의 주사위를 던졌을때 두눈의 합이 6이 되는 모든 경우의 수 출력
for (let i = 1; i <= 6; i++) {
for (let j = 1; j <= 6; j++){
if (i + j === 6) console.log(`[${i}, ${j}]`);
}
}
while문은 주어진 조건식의 평가 결과가 참이면 코드를 반복해서 실행한다.
for문은 반복 횟수가 명확할 때 주로 사용하고, while은 반복 횟수가 불명확할 때 주로 사용한다.
while문은 조건문의 평가 결과가 거짓이 되면 코드를 실행하지 않고 종료한다. 만약 조건식의 평가 결과가 불리언 값이 아니면 불리언 값으로 강제 변환하여 참,거짓을 구별한다.
// 3보다 작을 때까지 코드 반복 실행
let count = 0;
while (count < 3) {
console.log(count); // 0 1 2
count++;
}
// 무한루프 탈출 - if문으로 break
while (true) {
console.log(count);
count++;
if (count === 3) break;
}
do ... while문은 코드를 먼저 실행하고 조건식을 평가한다. 따라서 코드는 무조건 한 번 이상 실행된다.
// 3보다 작을 때까지 코드 반복 실행
let count = 0;
do {
console.log(count); // 0 1 2
count++;
} while (count < 3);
레이블문, 반복문(for, for..in, while, do...while), switch문의 코드 블록을 탈출하는 문이다. 이외에 break를 사용하면 에러가 난다. 반복문을 더이상 진행하지 않아도 될 때 불필요한 반복문을 회피할 수 있어 유용하다.
if (true) {break;} // 에러
//레이블문 - 식별자가 붙은 문
//프로그램 실행 순서를 제어하는 데 사용. switch문, case문, defualt문도 레이블 문이다.
//레이블문을 탈출하려면 레이블 식별자를 지정한다.
foo: console.log('foo');
foo: {
console.log(1);
break foo;
console.log(2);
}
console.log('done!');
//중첩 for문의 내부문에서 break 실행하면 내부 for문을 탈출해 외부 for문으로 진입한다.
//이때 내부가 아닌 외부 for문을 탈출하려면 레이블 문을 사용한다.
//outer라는 식별자가 붙은 레이블 for문
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
// i + j === 3이면 for문 탈출
if (i + j === 3) break outer;
console.log(`inner [${i}, ${j}]`);
}
}
레이블문은 중첩된 for문 외부로 탈출할 때 유용하지만, 그 밖의 경우에는 일반적으로 권장하지 않는다. 흐름이 복잡해져서 가독성이 나빠지고 오류를 발생시킬 가능성이 높아진다.
continue문은 반복문의 코드 블록 실행을 현 지점에서 중단하고 반복문의 증감식으로 실행 흐름을 이동시킨다. break문처럼 반복문을 탈출하지는 않는다.
//특정 문자의 개수를 세는 예시
let string = 'Hello World';
let search = 'l';
let count = 0;
for (let i = 0; i < string.length; i++) {
// l이 아니면 현 지점에서 실행을 중단하고 반복문의 증감식으로 이동.
if (string[i] !== search) continue;
count++; // continue문이 실행되면 이 문은 실행되지 않는다.
}
console.log(count); // 3
// string 메서드를 사용해도 같은 동작
const regexp = new RegExp(search, 'g');
console.log(string.match(regexp).length); // 3
// for문 예시
for (let i = 0; i < string.length; i++){
// l이면 카운트를 증가시킨다.
if (string[i] === search) count++;
}
위와 같이 if문 내에서 실행해야 할 코드가 한줄이면 if문을 쓰는 것이 좋지만, 코드가 길다면 continue문을 사용하는 편이 가독성에 좋다.