8. 제어문

해피데빙·2022년 7월 20일
0

제어문의 종류

  • 블록문
  • 조건문 : 조건에 따라 코드 불록을 실행할 때 사용
  • 반복문 : 반복 실행할 때 사용

제어문 사용 이유
:일반적으로 위에서 아래로 흐르는 코드의 실행 흐름을 인위적으로 제어할 수 있다

제어문의 단점
: 코드의 실행 순서가 변경된다는 것은 단순히 위에서 아래로 순차적으로 진행하는 직관적인 코드의 흐름을 혼란스럽게 만든다
-> 코드의 흐름을 이해하기 어렵게 만들어 가독성을 해치고 오류를 발생시킬 수 있다

함수형 프로그래밍
: 제어문의 사용을 억제하여 복잡성을 해결하려고 한다
ex. forEach, map, filter, reduce 같은 고차 함수를 사용, 가독성 up

블록문

블록문 : 0개 이상의 문을 중괄호로 묶은 것

  • 코드 블록 또는 블록이라고 부른다
{
}
  • 자바스크립트는 블록문을 하나의 실행 단위로 취급한다
  • 단독으로 사용
  • 일반적으로 제어문 정의
  • 함수를 정의할 때 사용
  • 세미콜론 X
    : 문의 끝에는 세미콜론을 붙이는 것이 일반적이지만 블록문은 언제나 문의 종료를 의미하는 자체 종결성을 갖기 때문에 블록문의 끝에는 세미콜론을 붙이지 않는다

예제

//블록문
{var foo = 10; }

//제어문 
var x=1; 
if(x<10){x++;}

//함수 선언문
function sum(a,b){return a+b}

조건문

  • 조건문 : 주어진 조건식의 평가 결과에 따라 코드 블록(블록문)의 실행을 결정한다
  • 조건식 : 불리언 값으로 평가될 수 있는 표현식
    - if...else문
    • switch문

if...else문

주어진 조건식(불리언 값으로 평가될 수 있는 표현식)의 평가 결과,
즉 논리적 참 또는 거짓에 따라 실행할 코드 블록을 결정한다

  • 조건식의 평가 결과가 true일 경우: if문의 코드 블록이 실행되고
  • false일 경우 : else문의 코드 블록이 실행된다
  • 조건식을 추가해 조건에 따라 실행될 코드 블록을 늘리고 싶으면 else if문을 사용한다
if(조건식1){
//조건식1이 참이면 실행
}else if (조건식2) {
//조건식2가 참이면 실행
}else{ 
//조건식1, 2가 모두 거짓이면 이 코드 블록 실행 
}
  • if, else는 1번/ else if는 무제한
  • 코드 블록 내의 문이 하나뿐이라면 중괄호를 생략할 수 있다

cf. 만약 if문의 조건식이 불리언 값이 아닌 값으로 평가되면?

  • 자바스크립트 엔진에 의해 암묵적으로 불리언 값으로 강제 변환되어 실행할 코드블록을 결정한다

삼항 조건 연산자
: 조건문은 삼항 조건 연산자로 바꿀 수 있다

var x =2; 

//0은 false로 취급 
var result = x%2 ? '홀수' : '짝수'; 
console.log(result);//짝수

삼항 조건 연산자에서 경우의 수가 세가지라면?

var num=2; 
//0은 false
var kind = num ? (num>0 ? '양수' : '음수'): '영'; 
console.log(kind)

삼항 조건 연산자 : 값으로 평가되는 표현식을 만든다
if...else문과 다르게 값처럼 사용할 수 있기 때문에 변수에 할당할 수 있다

정리

조건에 따라 단순히 값을 결정하여 변수에 할당하는 경우 : 삼항 조건 연산자
조건에 따라 실행해야 할 내용이 복잡해 여러 줄의 문이 필요한 경우 : if...else문

switch문

  • swtich문
    : 주어진 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 case문으로 실행 흐름을 옮긴다

  • case문
    : 상황을 의미하는 표현식을 지정하고 콜론으로 마친다.
    그리고 그 뒤에 실행할 문들을 위치시킨다

  • default문
    : 일치하는 case문이 없다면 실행 순서는 default문으로 이동한다.
    default문은 선택사항으로 사용할 수도 있고 사용하지 않을 수도 있다

switch(표현식){
	case 표현식1: 
    	switch 문의 표현식과 표현식1이 일치하면 실행될 문; 
        break;
    case 표현식2: 
    	switch 문의 표현식과 표현식2이 일치하면 실행될 문; 
        break; 
    default: 
    	switch문의 표현식과 일치하는 case문이 없을 때 실행될 문;
        여기는 break를 사용하지 않아도 실행이 종료되니까 필요 없다
       
}

if...else문 vs swtich문

  • if...else문의 조건식은 불리언 값으로 평가되어야 한다
  • switch문의 표현식은 불리언 값보다는 문자열이나 숫자 값이 경우가 많다

case문에 break를 사용하지 않을 경우
: switch문의 표현식의 평가 결과와 일치하는 case문으로 실행 흐름이 이동하여 문을 실행 후, fall through가 일어났기 때문

fall through란?
: switch문을 탈출하지 않고 이후 모든 case문과 default문을 실행하는 것

var month = 1; 
var monthName; 

switch(month){
	case 1: monthName = 'January'    
    case 2: monthName = 'February' 
    default: monthName = 'Invalid month'
}

console.log(monthName);//'Invalid month' 

위와 같이 되는 이유
: case 1과 일치해서 monthName에 January가 할당되지만 break가 없어서
아래 February도 재할당되고 default까지 Invalid month가 또 재할당된다

swtich문

  • 일치하는 값을 찾는다
    - break가 있으면 거기서 switch문이 끝난다
    • break가 없으면 일치하지 않더라도 아래 case들을 다 돌고 default까지 돌면서 재할당된다
  • 일치하는 값이 없으면 default문에서 재할당된다

cf. break : 코드 블록에서 탈출하는 역할
break문이 없다면 case문의 표현식과 일치하지 않더라도 실행 흐름이 다음 case문으로 연이어 이동한다

여러 case를 한 번에 사용하기

//윤년 계산 알고리즘 
1. 연도가 4로 나누어 떨어지는 해 
2. 4로 나누어 떨어지더라도 100으로 나누어 떨어지면 안된다 
3. 400으로 나눠떨어지면 윤년

var year = 2000; 
var month=2; 
var days=0; 

switch(month){
 case1: case3: case5: case7: case8: case 10: case12: 
 	days = 31; 
    break; 
 case4: case6: case9: case11: 
 	days=30; 
    break; 
 case 2: 
 //
   days = ((year%4 ===0 && year%100 !==0) || (year%400===0)) ? 29 : 28;
   break; 
 default: 
 	console.log('Invalid month');
}
console.log(days);
}

정리

if...else문을 사용하는 편이 좋다. 조건문이 너무 많은 경우에먼 가독성을 위해 switch사용

반복문

  • 조건식의 평가 결과가 참인 경우 코드 블록 실행
  • 조건식을 다시 평가해 여전히 참인 경우 코드 블록을 다시 실행
  • 조건식이 거짓일 때까지 반복

for문
while문
do...while문

반복문 대신 사용할 수 있는 것들

forEach 메서드 : 배열 순회 시 사용
for...in문 : 객체의 프로퍼티 열거 시 사용
for...of문 : ES6에서 도입된 이터러블 순회할 때 사용 ex. 배열

for문

조건식이 거짓으로 평가될 때까지 코드 블록을 반복 실행한다

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

실행 순서

  1. 변수 선언문 var i=0 실행 (단 한번만 실행된다)
  2. 변수 선언문의 실행이 종료되면 조건식 실행
  3. 조건식 평가 결과가 true면 코드 블록 실행
  4. 코드 블록 실행 종료 시 증감식 i++
  5. 증감식 실행 종료 시 다시 조건식 실행
    3~5번 반복
    n. 조건식 실행 시 false면 for문의 실행 종료
  • 역으로도 할 수 있다 : 증감식을 i--로 하면
  • 변수 선언문, 조건식, 증감식 모두 옵션
  • 단, 어떤 식도 선언하지 않으면 무한루프 (코드 블록 무한히 반복 실행)
for(;;){...}
  • 중첩 for문: for문 내에 for문을 중첩해 사용하는 것

while문

주어진 조건식의 평가 결과가 참이면 코드 블록을 계속해서 반복 실행

for문 vs while문

  • for : 반복 횟수가 명확할 때 사용
  • while : 반복 횟수가 불명확할 때 사용
  • 종료 : while문은 조건문의 평가 결과가 거짓이 되면 코드 블록을 실행하지 않고 종료
  • 조건식의 평가 결과가 불리언 값이 아니면 : 불리언 값으로 강제 변환
  • 조건식의 평가 결과가 참이면 무한루프
  • 무한 루프 탈출 위해서는 코드 블록 내에 if문으로 탈출 조건을 만들고 break문으로 코드 블록 탈출한다
var count=0; 

while(true){ 
	console.log(count) 
    count++; 
    
    if(count ===3)break;
}

do...while문

코드 블록을 먼저 실행하고 조건식을 평가한다
-> 코드블록 무조건 한 번 이상 실행

var count=0; 

do{
console.log(count); 
count++;
}while(count<3) 

break문

  • 레이블 문, 반복문(for, for...in, for...of, while, do, do...while) 또는 switch문의 코드 블록을 탈출
  • 이외에서 사용하면 문법 에러 발생
  • 반복문을 더 이상 진행하지 않아도 될 때 불필요한 반복을 회피할 수 있어서 유용하다

cf. 레이블문 : 식별자가 붙은 문. 프로그램의 실행 순서를 제어하는 데 사용한다
switch문의 case문과 default문도 레이블 문
ex.

  • 레이블 문을 탈출하려면 break문에 레이블 식별자를 지정한다
foo:{
console.log(1); 
break foo; //foo레이블 블록문을 탈출한다
console.log(2);
}
var string='Hello World'; 
var search='l' 
var index; 

for(var i=0; i<string.length; i++){ 
	if(string[i]===search){ 
    	index=i; //찾았으면 반복문 탈출
        break;
    }
} 

console.log(index);
  • 중첩된 for문의 내부 for문에서 break문을 실행하면 내부 for문을 탈출하여 for문으로 진입한다
  • 이때 내부 for문이 아닌 외부 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!');

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

continue문

  • 반복문의 코드 블록 실행을 현 지점에서 중단하고 반복문의 증감식으로 실행 흐름을 이동
  • break문처럼 반복문을 탈출하지는 않는다
let str = 'hello world'
var search = 'l'
var count=0; 

for(var i=0; i<string.length; i++){
	if(string[i] !== search) continue; //현 시점에서 실행 중단, 반복문의 증감식으로 이동
    count++; //continue가 실행되면 이 문은 실행되지 않는다
}

console.log(count); 
//continue문을 사용하지 않으면 if문 내에서 코드를 작성해야 한다 

for(var i=0; i<string.length; i++){
	if(string[i] !== search) {
    count++; //continue가 실행되면 이 문은 실행되지 않는다
    }
}

console.log(count); 
profile
노션 : https://garrulous-gander-3f2.notion.site/c488d337791c4c4cb6d93cb9fcc26f17

0개의 댓글