0%

제어문

1. 블록문

블록문는 0개이 상의 문을 중괄호로 묶은것으로 콛블록 또는 블록이라고 부르기도 한다. 자바스크립트는 블ㄹ고문을 하나의 시랳아 단위로 취급한다. 블록문은 단독으로 사용할 수도 있으나 일반적으로 제어문이나 함수를 정의할때 상요하는 것이 일반적이다.
블록문이 사용되는 다양한 예제가 있다. 문의 끝에는 세미 콜론을 붙이는 것이 일반적이다. 하지만 블록 문은 언제나 문의 종료를 의미하는 자체 종결성을 갖기 때문에 블록문의 끝에는 세미콜론을 붙이지 않는다는 것에 주의하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
//블록문
{
var foo = 10;
}
//제어문
var x =1;
if(x<10){
x++
}
//함수 선언문
function sum(a,b){
return a+b;
}

2. 조건문

조건문은 주어진 조건식의 평가 결과에 따라 코드블록의(블록문)의 실행을 결정한다. 조건식은 불리언 값으로 평가 될 수있는 표현식이다. 자바스크립트는 2가지의 조건문 if …else if 문과 switch문을 제공한다.

2.1. if … else if 문

if .. else 문은 주언진 조건식(불리언 값으로 평가 될수 있는 표현식)의 평가 결과,즉 놀리적 참 또는 거짓에 따라 실행할 코드 블록을 결정한다. 조건식의 평가 결과가 참일 경우,if 문 다음의 코들 블록이 실행되고 거짓일 경우 else일경우 다음의 코드 블록이 실행된다.

1
2
3
4
5
if(조건식){
//조건식이 참이면 이 코드 블록이 실행된다.
}else{
//조건식이 거짓이면 이 코드 블록리 실행된다.
}

if의 조건식은 불리언 값으로 평가 되어야한다. 만약if문의 조건식이 불리언값이 아닌 다른 값으로 평가 되면 자바스크립트 엔진에 의해서 암묵적으로 데이터 타입이 불리언 값으로 강제로 변환이 되어 실행할 코드 블록을 결정한다.
조건식을 추가하여 조건에 따라 실행될 코드 블록을 늘리고 싶으면 else if문을 사용한다.

1
2
3
4
5
6
7
if(조건식){
//조건식1이 참이면 이 코드 블록을 실행
}else if(조건식){
//조건식2이 참이면 이 코드블록을 실행
}else{
//조건식1과 조건식2가 모두 거짓이면 이 코들 블록을 실행
}

else if문과 else문은 옵션이다. 즉 사용 할 수도 있고 사용하지 않을 수도 있다. if문과 else문은 2번이상 사용할수 없지만 else if문은 2 이상 사용 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var num =2;
var kind;
//if문
if(num > 0){
kind ='양수';//양수
}
console.log(kind);

//if else 문
if(num>0){
kind = '양수';
}else{
kind ='음수'
}
console.log(kind//양수

//if else if문
if(num > 0){
kind ='양수';
}else if(num <0){
kind = '음수';
}else{
kind = '영'
}
console.log(kind); //양수

만약에 코드 블록의 문이 하나라면 중괄호를 생략 할 수 있다.

1
2
3
4
5
6
var num =2;
var kind;
if(num > 0 )kind = '양수';
else if(num < 0)kind = '음수';
else kind = '영';
console.log(kind) //양수

대부분의 if…else 문은 삼항 조건 연산자로 바꿔 사용가능하다.

1
2
3
4
5
6
7
8
var x =2;
var result;
if(x % 2){
result = '홀수'
}else{
result = '짝수';
}
console.log(result) //짝수
1
2
3
var x = 2;
var result = (x % 2 )? '홀수':'짝수';
consoel.log(result) //짝수
1
2
3
var num = 2;
var kind = num ? (n >0? '양수': '음수'):'영'
console.log(num) //양수

(n >0? ‘양수’: ‘음수’)는 표현식이다. 즉 삼항 조건 연산자는 값으로 평가되는 표현식을 만든다. 하지만 if . else 문은 표현식이 아닌 문이다. 따라서 삼항 조건 연산자 표현식은 값 처럼 사용 할 수 있기 때문에 변수 할당 할 수 있다.하지만 if..else문은 값처럼 사용 할수 없다는 차이가 있다. 따라서 조건에 따라 단순히 값을 결정하는 경우 if ..else문 보다 삼항 조건 연산자를 사용하는 것이 가독성이 좋다. 하지만 조건에 따라 실행하여야 하는 내용이 복잡하여 여러 줄의 문이 필요하다면 if ..else문을 사용 하는 평이 가독성이 좋다.

2.2. switch문

switch문은 주어진 표현식을 형가하여 그 값과 일치하는 표현식을 갖는 case문으로 실행하는 순서를 이동 시킨다. case문은 상화을 의미하는 표현식을 지정하고 콜론으로 마친다. 그리고 그 뒤에 실행 할 문들을 위치 시킨다.
switch문의 표현식과 일치하는 표현식을 갖는 case문이 없다면 실행 순서는 default 문으로 이동한다. default 문은 옵션으로 사용 할 수 있고 않을 수도 있다.

1
2
3
4
5
6
7
8
9
10
switch(표현식){
case 표현식1:
switch 문의 표현식과 표현식1이 일치하면 실행될 문;
break;
case 표현식2:
switch 문의 표현식과 표현식2이 일치하면 실행될 문;
break;
default:
switch 문의 표현식과 일치하는 표현식을 갖는 case문이 없을 때 실핼될 문
}

else if 문의 조건식은 불리언 값으로 평가되어야 하지만 , switch 문의 표현식은 불리언 값 보다는 문자열 ,숫자 값인 경우가 많다. if ..else 문은 논리적 참,거짓으로 실행할 코들 블록을 결정한다.switch문은 논리적참,거짓 보다 다양한 상황에 따라 실행될 코드 블록을 결정 할 때가 많다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var month = 11;
var monthName;

switch (month) {
case 1: monthName = 'January';
case 2: monthName = 'February';
case 3: monthName = 'March';
case 4: monthName = 'April';
case 5: monthName = 'May';
case 6: monthName = 'June';
case 7: monthName = 'July';
case 8: monthName = 'August';
case 9: monthName = 'September';
case 10: monthName = 'October';
case 11: monthName = 'November';
case 12: monthName = 'December';
default: monthName = 'Invalid month';
}

console.log(monthName); // November

그런데 위 예제를 실행해 보면은 ‘November’가 출력되지 않고 ‘Invalid month’을 출력한다. 이는 switch문의 표현식의 평가 결과와 일치하는 case 문으로 실행한 것은 맞지만 ,문을 실행한 후 switch문을 탈출 하지않고 switch문이 끝날 때 까지 이후의 모든 case문과 default문을 실행 했기 때문이다. 이를 폴 스루 했다고 한다. 다시 말해 변수 monthName에 ‘November’가 할당된 후 switch 문을 탈출 하지않고 연이어 재할되기 때문이다. 때문에 ‘Invalid month’출력된다.
결과가 이러한 이유는 case문에 해당하는 문의 마지막 break문을 사용하지 않았기 때문이다. break 키워드로 구성된 break문은 코드 블록에서 탈출하는 역할을 한다. break문이 없다면 case문의 표현식과 일치하지 않더라도 실행 순서는 다음 case문으로 연이어 이동한다. 올바른 switch문의 예는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var month = 11;
var monthName;

switch (month) {
case 1: monthName = 'January';
break;
case 2: monthName = 'February';
break;
case 3: monthName = 'March';
break;
case 4: monthName = 'April';
break;
case 5: monthName = 'May';
break;
case 6: monthName = 'June';
break;
case 7: monthName = 'July';
break;
case 8: monthName = 'August';
break;
case 9: monthName = 'September';
break;
case 10: monthName = 'October';
break;
case 11: monthName = 'November';
break;
case 12: monthName = 'December';
break;
default: monthName = 'Invalid month';
}

console.log(monthName); // November

deafult 문에는 break문을 생략하는 것이 일반적이다. default문은 switch문의 가장 마지막에 위치하므로 defualt문의 실행은 따라서 별도의 break문이 필요 없다.

break문을 생략한 폴 스루가 유용한 경우도 있다 폴스루는 여러개의 case문을 하나의 조건으로 사용할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var year =2020;
var month = 5;
var days = 12;

switch(month){
case 1 :case 3:case 5: case 7: case 10: case 12:
days = 31;
break;
case 4:case 6: case 11:
days = 30;
break;
case 2:
days =((year % 4 ===0 && year % 100 !== 0) || (yaer % 400 === 0))?29:28;
break;
default:
console.log('Invalid month');
}
console.log(days);

switch문은 case, default,break등 다양한 키워드를 사용해야하고 상화에 따라 실행될 코들 블록리 중괄호로 붂어 있지 안흥며 폴스루가 발생하는 등 문법도 복잡하다. 따라서 C언어를 기반으로 하는 프로그래밍 언어는 대부분 switch문을 지원하지만 피이썬과 같이 switch문을 지원 하지 않는 프로그래밍 언어도 존재한다.
만약 if ..else문으로 해결 할 수 있다면 switch문 보다 if ..else문을 사용했을때 가독성이 더 좋다. 하지만 if…else 문보다는 switch 문을 사용했을때 더 가독성이 좋다면 switch문을 사용하는 편이 좋다.

3. 반복문

반복문은 주어진 조건식의 평가 결과가 참인 경우 코드블럭을 실행한다. 그 후 저건식을 다시 검사하여 여전히 참인 경우 코드블록을 다시 실행한다. 이는 조건식이 거짓일때 까지 반복한다.
자바스크립트는 3가지의 반복문 for문 while문 do while문 을 제공한다.
반복문을 대체 할 수 있는 다양한 기능

자바스크립트는 배열을 순회할때 사용하는 forEach 메소드,객체의 프로퍼티를 열거할 때 사용하는 for ..in문 Es6에서 새롭게 이터러블을 순회할 수 있는 for..of문과 같이 반복문을 대체 할 수 있는 다양한 기능을 제공한다.

3.1. for문

for문은 조건식이 거짓으로 판별 될때 까지 코드 블록을 반복 실행한다. 가장 일반적으로 사용되는 for문의 형태는 다음과 같다. 변수 선언문의 변수이름은 반복을 의미하는 iteration의 i을 사용하는 것이 일반적이다.

1
2
3
for(변수 선언문 또는 할당문;조건식;증감식){
조건식이 참인 경우 반복 실행될 문;
}
1
2
3
for(var i =0;i<2;i++){
consoel.log(i) // 0 1
}

img

for문의 변수 선언문,조건식,증감식은 모구 옵션이다. 반드시 사용할 필요는 없다. 어떤식도 선언하지 않으면 무한 루프가 된다.

1
2
//무한 루프
for(;;){...}
1
2
3
4
5
6
7
8
9
10
11
12
13
for(var i = 0;i<=6;i++){
for(var j =0;j<=6;j++){
if(i+j === 6){
console.log(`[${i},${j}]`);
}
}
}
// 결과
[1, 5]
[2, 4]
[3, 3]
[4, 2]
[5, 1]

3.2. while문

while문은 주언진 조건식의 평가가 참이면 코드블록을 계속해서 반복 실행한다. 조건문의 평가 결과가 거짓이면 실행을 종료한다. 만약 조건식의 평가 결과가 블리언 값이 아니면 불리언 값으로 강제 변환되어 논리적 참 거짓을 구별하게 된다.

1
2
3
4
5
6
var count = 0;
//count가 3보다 작을 때 까지 코드블록을 계속 반복 실행한다.
while(count <3){
console.log(count); // 0 1 2
count++
}

조건식의 평가 결과 가 언제나 참이면 무한 루프를 돈다.

1
while(true){...}
1
2
3
4
5
6
7
8
9
10
//무한 루프를 탈출하기 우해서 조건을 만들고 break을 사용하여 탈출한다.
var count =0;
//무한 루프
while(true){
consoel.log(count);
count++;
//count가 3이면 코들블록을 탈출한다.
if(count ===3)break;
//0 1 2
}

3.3. do while문

do…while문은 코드블록을 먼저 실행하고 조건식을 평가한다. 따라서 코드블록은 무조건 한번이상 실행된다.

1
2
3
4
5
6
var counr =0;
//count가 3보다 작을때 까지 코드블록을 곗고 반복 실행;
do{
console.log(count);
count++;
}while(count <3) //0 1 2;

4. break문

switch문과 while문 네서 살펴 보았듯이 break문은 코드 블록을 탈출한다. 좀 더 정확히 말하면 코드블록을 탈출하는 것이 아니라 레이블문 ,반복문(for,for..in,for…of ,while문,do…while문) 또는 switch문의 코드블록을 탈출한다.
레이블 문,반복문,switch 문의 코드블록 이외에 break 문을 사용하면 SyntaxError문법에러가 발생한다.

1
2
3
if(true){
break;// Uncaught SyntaxError: Illegal break statement
}

레이블 문(label statement)이란 식별자가 붙은 문을 말한다.

1
2
//foo라는 레이블 식별자가 붙은 레이블 문
foo: console.log('foo');

레이블 문은 프로그램의 실행 순서를 제어하기 위햇 사용한다. 사실 switch 문의 case문과 default도 레이블 문이다. 레이블 문을 탈출하려면 break 문에 레이블 식별자를 지정한다.

1
2
3
4
5
6
7
//foo라는 식별자가 붙은 레이블 블록문
foo:{
console.log(1);
break foo;//foo 레이블 블록문을 탈출한다.
console.log(2);
}
console.log('Done');

중첩된 for 문의 내부 for문에서 break문을 실행하면 내부 for문을 탈출하여 외부 for문으로 진입한다. 이때 내부for문이 아닌 외부 for문을 탈출하려면 레이블문을 사용한다.

1
2
3
4
5
6
7
8
9
//outer라는 식별자가 붙은 레이블 for문
outer:for(var i = 0;i < 3;i++){
for(var j = 0;j<3;j++){
//i+j === 3 이면 outer라는 식별자가 붙은 레이블 for문을 탈출한다.
if( i+j === 3) break outer;
console.log(`inner [${i},${j}]`);
}
}
console.log('Done!');

레이블 문은 중첩된 for문 외부로 탈출할 때 유용하지만 그 외의 경우 레이블 문은 일반적으로 권장 하지않는다. 레이블 문을 사용하면 프로그램의 흐름이 복잡해져서 가독성이 나빠지고 오류를 발생시킬 가능성이 높아지기 때문이다.

break문은 레이블 문 뿐 만이 아니라 반복문,switch문에서도 사용 할 수 있다. 이 경우에는 break문에 레이블 식별자를 지정하지 않는다. break문은 반복문을 더 이상 진행하지 않아도 될때 불필요한 반복을 회피할 수 있어 유용하다.

아래는 문자열에서 특정한 인덱스의 위치를 검색하는 예제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var string = 'Hello world';
var search = 'l';
var index ;
//문자열은 유사배열이므로 for문으로 순회할 수 있다.
for(var i =0;i < string.length;i++){
//문자열의 개별 문자가 'l'이면;
if(string[i] === search){
index = i;
break; //반복문은 탈출한다.
}
}
console.log(index) //2;

consoel.log(string.indexOf(search)) //2

5. continue문

continue문은 반복문의 코드블록 실행 을 현 시점에서 중담하고 반복문의 증감식으로 이동한다. break문처럼 반복문을 탈출하지않는다.
문자열에서 특정 문자의 개수를 카운트하는 예제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var string = 'Hello world';
var search ='l';
var index ;

for(var i =0;i<string.length;i++){
if(string [i] !== serach) continue;
//string[i] === 'l'일때에만 아래의 count++가 실행된다.
//string[i] !== 'l'일 때에는 for문의 조건의 증감식으로 이동한다.
count++
}
console.log(count) //3;

const regexp =new RegExp(search,'g');
console.log(string.match(regexp).length); //3
1
2
3
4
5
for(var i =0;i<string.length;i++){
if(string[i] === search){
count++;
}
}

위와 같이 if문 내에서 실행해야 할 코드가 한 줄이라면 continue문을 사용했을때 보다 간편하며 가독성이 좋다. 하지만 if문 내에서 실행할 코드가 길다면 들여쓰기가 한 단계 더 깊어지므로 continue 문을 사용하는 것이 가독성이 더 좋다.

1
2
3
4
5
6
7
8
9
10
11
12
13
// continue 문을 사용하지않으면 if문 내에 코드를 작성해야한다.
for(var i =0;i<string.length;i++){
//'l'이면 카운트를 증가 시킨다.
if(string[i] === search){
count++
}
}
//continue 문을 사용하면 id문 밖에 코드를 작성할수있다.
for(var i =0;i<string.length;i++){
//'l'이 아니면 카운트를 증가 시키지 않는다.
if( string[i] !== search) continue;
count++;
}