모던 자바스크립트 Deep Dive - 제어문
제어문(control flow statement)은 조건에 따라 코드 블록을 실행 하거나 반복 실행할때 사용한다. 제어문을 사용하면 코드의 실행 흐름을 인위적으로 제어할 수 있다.
블록문
블록문은 0개 이상의 문을 중괄호로 묶은 것으로, 코드 블록 또는 블록이라고 부른다. 자바스크립트에서는 블록문을 하나의 실행 단위로 취급한다. 일반적으로 제어문이나 함수를 정의할 때 사용하는 것이 일반적이다.
블록문은 언제나 자체 종결성을 갖기 때문에 끝에 세미콜론을 붙이지 않는다.
// 블록문
{
var foo = 100;
}
// 제어문
var x = 160;
if( x < 150 ) {
x ++;
}
// 함수 선언문
function sum(a, b) {
return a + b;
}
조건문
조건문(conditional statement) 은 주어진 조건식(conditional expression)의 평가에 따라 코드 블록을 실행한다.
조건식은 불리언 값으로 평가될 수 있는 표현식이다.
자바스크립트에는 if else 와 switch 문 두 가지가 존재한다.
if else
if (조건식) {
// 조건식이 참이면 이 코드 블록이 실행된다.
} else {
// 조건식이 거짓이면 이 코드 블록이 실행된다.
}
조건식을 추가하여 조건에 따라 실행될 코드 블록을 늘리고 싶으면 else if 문을 사용한다.
if (조건식1) {
// 조건식1이 참이면 이 코드 블록이 실행된다.
} else if (조건식2) {
// 조건식2가 참이면 이 코드 블록이 실행된다.
} else {
// 조건식1과 조건식2가 모두 거짓이면 이 코드 블록이 실행된다.
}
대부분의 if else 문은 삼항 조건 연산자로 바꿔 쓸 수 있다.
var x = 10;
var result;
if( x % 2 ) { // x가 짝수이면 x % 2 는 0이 된다. 이때 0은 암묵적 형 변환에 의해 false 로 강제 변환된다.
result = '홀수';
} else {
result = '짝수';
}
console.log(result); // 짝수
// 삼항 연산자
var x = 10;
var result = x % 2 ? '홀수' : '짝수';
console.log(result); // 짝수
switch
switch 문은 주어진 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 case 문으로 실행 흐름을 옮긴다.
case문은 상황(case)을 의미하는 표현식을 지정하고 콜론으로 마친다. 그리고 그 뒤에 실행할 문들을 위치시킨다.
switch 문의 표현식과 일치하는 case 문이 없다면 실행 순서는 default 문으로 이동한다. default 문은 선택사항으로, 사용할 수도 있고 사용하지 않을 수도 있다.
switch ( 표현식 ) {
case 표현식1:
switch 문의 표현식과 표현식1이 일치하면 실행될 문;
break;
case 표현식2:
switch 문의 표현식과 표현식2가 일치하면 실행될 문;
break;
default:
switch 문의 표현식과 일치하는 case 문이 없을 때 실행될 문;
}
switch 문은 논리적 참, 거짓보다는 다양한 상황에 따라 실행할 코드 블록을 결정할 때 사용한다.
// 성적을 영어로 변환
var grade = 80;
var gradeName;
switch (grade) {
case 100 :
gradeName = 'A';
case 90 :
gradeName = 'B';
case 80 :
gradeName = 'C';
default :
gradeName = 'F';
}
console.log(gradeName); // F
위의 예제를 보면 'C'가 출력되지 않고 'F'가 출력된다. 이는 switch 문의 표현식 평가와 일치파는 case 문으로 실행 흐름이 이동하여 문을 실행한 것은 맞지만 문을 실행한 후 switch 문을 탈출하지 않고 switch 문이 끝날 때까지 이후의 모든 case 문과 default 문을 실행했기 때문이다. 이를 풀스루(full through)라고 한다.
이러한 결과가 나타난 이유는 case 문 마지막에 break 문을 사용하지 않았기 때문이다.
var grade = 80;
var gradeName;
switch (grade) {
case 100 :
gradeName = 'A';
break;
case 90 :
gradeName = 'B';
break;
case 80 :
gradeName = 'C';
break;
default :
gradeName = 'F';
}
console.log(gradeName); // C
default 문에는 break 문을 생략하는 것이 일반적이다. switch 문의 맨 마지막에 위치하므로 default 문의 실행이 종료되면 switch 문을 빠져나간다.
반복문
반복문(loop statement) 은 조건식의 평가 결괴가 참인 경우 코드 블록을 실행한다. 그 후 조건식을 다시 평가하여 여전히 참인 경우 코드 블록을 다시 실행한다. 이는 조건식이 거짓일 때까지 반복된다.
자바스크립트는 세 가지 반복문인 for 문, while 문, do while 문을 제공한다.
for 문
for 문은 조건식이 거짓으로 평가될 때까지 코드 블록을 반복 실행한다.
for (변수 선언문 또는 할당문; 조건식; 증감식) {
조건식이 참인 경우 반복 실행될 문;
}
for( var i = 0; i < 2; i++) {
console.log(i);
}
// 0
// 1
for 문 내에 for 문을 중첩해 사용할 수 있다.
// 두 개의 주사위를 던져 두 눈의 합이 6이 되는 모든 경우의 수 출력
for ( var i = 1; i <= 6; i++) {
for( var j = 1; j <= 6; j++) {
if( i + j === 6) console.log(`[${i}, ${j}]`);
}
}
while 문
while 문은 주어진 조건식의 평가 결과가 참이면 코드 블록을 계속해서 반복 실행한다. for 문은 반복 횟수가 명확할 때 주로 사용하고 while 문은 반복 횟수가 불명확할 때 주로 사용한다.
while 문은 조건문의 평가 결과가 거짓이 되면 코드 블록을 실행하지 않고 종료한다. 만약 조건식의 평가 결과가 불리언 값이 아니면 불리언 값으로 강제 변환하여 논리적 참, 거짓을 구별한다.
var count = 0;
while ( count < 3 ) {
count++;
}
console.log(count); // 3
조건식의 평가 결과가 언제나 참이면 무한루프가 된다.
무한루프에서 탈풀하기 위해서는 코드 블록 내에 if 문으로 탈출 조건을 만들고 break 문으로 코드 블록을 탈출한다.
var count = 0;
while (true) { // 무한루프
console.log(count);
count++;
// count 가 3이면 탈출
if(count === 3) break;
}
// 0 1 2
do while 문
do while 문은 코드 블록을 먼저 실행하고 조건식을 평가한다. 따라서 코드 블록은 무조건 한 번 이상 실행된다.
var count = 0;
// count 가 3보다 작을 때까지 코드 블록을 계속 반복 실행한다.
do {
console.log(count); // 0 1 2
count++;
} while ( count < 3);
break문
위의 예제에서 보았듯 break 문은 코드 블록을 탈출한다. 레이블 문, 반복문, switch 문의 코드 블록 외에 break 문을 사용하면 SyntaxError(문법 에러) 가 발생한다.
레이블 문은 프로그램의 실행 순서를 제어하는 데 사용된다. switch 문의 case 문과 default 문도 레이블 문이다. 레이블 문을 탈출하려면 break 문에 레이블 식별자를 지정한다.
// foo 라는 레이블 식별자가 붙은 레이블 문
foo: {
console.log(1);
break foo; // foo 레이블 블록문을 탈출한다.
console.log(2);
}
console.log('Done');
// 1
// Done
중첩된 for 문의 내부 for 문에서 break 문을 실행하면 내부 for 문을 탈출하여 외부 for 문으로 진입한다.
이때 내부 for 문이 아닌 외부 for 문을 탈출하려면 레이블 문을 사용해야한다.
// outer 라는 식별자가 붙은 레이블 for 문
outer : for(var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
if(i + j == 3) {
break outer;
}
console.log(`inner ${i}, ${j}`);
}
}
console.log('Done');
// inner 0, 0
// inner 0, 1
// inner 0, 2
// inner 1, 0
// inner 1, 1
// Done
continue 문
continue 문은 반복문의 코드 블록 실행을 현 지점에서 중단하고 반복문의 증감식으로 실행 흐름을 이동한다. break 문처럼 반복문을 탈출하지는 않는다.
var string = 'Hello';
var search = 'l';
var count = 0;
for(var i = 0; i < string.length; i++) {
if(string[i] === search) continue;
count++;
}
console.log(count); // 3