ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JavaScript] 자바스크립트 switch문 조건문 이해하기
    프로그래밍 이야기/JavaScript 공부 2020. 5. 8. 02:08

    if문과 삼항 연산자 외에 자바스크립트에서 조건에 따라 다른 동작을 하는 것이 하나가 더 있었다.

    바로 switch문이다. 
    조건식을 두고 조건의 진위 여부에 따라 동작을 수행하는 if문과는 다르게

    switch문은 어떤 값을 가진 대상을 두고 조건값일치하는지를 확인하고 동작을 수행하는 방식이다.

     

    문법

    문법은 다음과 같다. 

    switch (대상) {
        case 조건값1:
            동작
            break; // 생략가능
        case 조건값2:
            동작
            break; // 생략가능
        
        // ...
        
        default:
            동작
    }

     

    switch라는 키워드 뒤에 소괄호를 열어 비교할 대상을 작성하고, 중괄호로 블록문을 만든다.

    블록문 안에 한 번 들여 써서 case 키워드를 작성하고 조건값을 입력한 뒤 콜론(:)으로 case문의 끝 지점을 구분해 준다.

    참고로 이렇게 쓰는 문장을 라벨문, 레이블문, lable statement라고 부른다.

    case문 안에서, 해당 조건값과 일치했을 때 동작해야 될 코드를 작성하면 된다.

    뒤에서 정리하겠지만 break 키워드는 switch 블록문을 빠져나가는 구문으로,

    해당 조건을 만족한 뒤 필요한 동작을 한 다음은 블록문을 빠져나오는 것이 일반적이기 때문에

    생략이 가능하지만, 작성해주는 경우가 더 많다.

    마지막으로 default라는 키워드를 입력하고 콜론으로 default문을 구분한 뒤

    한 번 들여 써서 모든 조건값들과 비교해서 일치하는 결과가 없을 경우에 필요한 동작을 작성하면 된다.
    else문 같은 느낌으로, 반드시 필요한 구문은 아니기 때문에 얼마든지 생략도 가능하다.

    let a = 2;
    
    switch(a) {
        case 1:
            console.log('a는 1입니다.');
            break;
        case 2:
            console.log('a는 2입니다.'); // a는 2입니다.
            break;
        default:
            console.log('a는 1도 2도 아닙니다.');
    }

    위 코드는 'a는 2입니다'가 콘솔에 출력된다.

     

    break문의 역할과 이유

    break는 앞서 설명한 것처럼 switch의 중괄호를 빠져나가는 명령어다.

    switch문은 처음 대상과 조건값들의 일치 비교를 한 다음,

    break문을 만나기 전까지 해당되는 case문 혹은 default문 이후의 모든 동작들을 수행한다.

    바로 직전 코드를 break문 없이 작성하면 아래와 같이 작성할 수 있는데,

    let a = 2;
    
    switch(a) {
        case 1:
            console.log('a는 1입니다.');
        case 2:
            console.log('a는 2입니다.'); // a는 2입니다.
        default:
            console.log('a는 1도 2도 아닙니다.'); // a는 1도 2도 아닙니다.
    }

    콘솔에는 'a는 2입니다.'와 'a는 1도 2도 아닙니다.'가 모두 출력이 된다.

    코드를 살펴보면 switch문이 실행될 때 두 번째 case문의 조건값과 일치하기 때문에

    자연스럽게 두 번째 case 문의 동작 부분을 수행한 다음,

    break문이 없기 때문에 그다음 동작부도 수행해 버린 것이다.
    그다음 동작이 switch 문의 마지막 동작이었기 때문에 거기서 종료된 것이지,

    만약 더 많은 case가 있었다면 break문을 만나기 전까지 모두 실행했을 것이다.

     

    아무튼, 이런 의미에서 보면, 

    case문은 조건값에 따라 동작들을 하나하나 구분하는 것이 아니라

    switch문 내부의 여러 동작들 중에서 가장 먼저 동작할 시작점을 찾는 기준이라고 생각해도 좋을 것 같다.

    그래서 case별로 동작들을 구분하고 싶다면 필요한 구간에 반드시 break문을 작성해줘야 한다.

     

    추가적으로, 간혹 switch문 마지막에 default문을 작성하고 그 뒤에 break문을 작성하는 경우가 있는데,

    break문의 역할을 생각해 본다면 사실상 switch문의 가장 마지막 닫는 중괄호( ) 직전에 위치하는 break문은

    통일성을 고려한다거나, 혹은 위치 조정을 염두한다거나,

    무언가 특별한 이유가 아니라면 굳이 작성할 필요가 없는 코드이다.

     

    default문의 위치

    처음 switch문을 접할 때 대부분 default문의 위치가 가장 마지막이다 보니

    항상 default문은 마지막에 와야 한다는 오해를 하곤 했었다.

    아무래도 if문에 빗대면 default문이 else에 해당하는 역할이다 보니 그랬을 수도 있겠지만

    아무튼, switch문에서 default문은 그 위치가 어디에 있건 상관이 없다.

    let a = 0;
    
    switch(a) {
        case 1:
            console.log('a는 1입니다.');
            break;
        default:
            console.log('a는 1도 2도 아닙니다.'); // a는 1도 2도 아닙니다.
            break;
        case 2:
            console.log('a는 2입니다.');
    }

    default가 가장 먼저 등장하는 것도 당연히 동작하거니와, 심지어 case문 중간에 들어가 있어도 무리 없이 동작한다. 

    바로 직전에도 언급했지만 case와 defalut는 결국 동작 부분을 구분하는 것이 아니라,

    switch문 내부의 여러 동작들 중에서 가장 먼저 동작할 시작점을 찾는 기준일 뿐인 것이다.

     

    그럼에도 불구하고 default문이 많은 예제에서 가장 마지막에 나오는 이유는 무엇일까?

    당연히 사람이 코드를 읽고 해석할 때 코드의 가독성면에서 default가 마지막에 나오는 것이 가장 이해하기가 쉽다. 

    default가 중간에 끼여있는 것은 당연히 해석하는데 어려움이 있을 것이고,

    가장 먼저 나오는 것은 그나마 괜찮을 수 있지만, 아무래도 위에서부터 아래로 읽어나가는 방향을 생각했을 때

    필요한 조건들을 다 확인한 뒤 예외인 것을 확인하는 것이 자연스럽다.

     

    응용 

    let optionGrade = 2;
    let option = '';
    
    switch(optionGrade) {
        case 1:
            option += '전동 트렁크, 선루프, HUD, ';
        case 2:
            option += '크루즈 컨트롤, 전후방 감지기, 전후방 카메라, ';
        case 3:
            option += '열선 및 통풍 시트, 스마트 키, 네비게이션, ';
        default:
            option += '에어백, 차선이탈 경보장치, 무선도어 잠금장치';
    }
    
    console.log(option);

     

     

    자 위 코드를 살펴보자.

    자동차를 구매할 때 등급에 따라 옵션이 다른 경우를 표현한 것인데,

    break문이 없음에도 불구하고, switch문을 의도에 맞게 작성할 수 있었다.

     

    이 코드를 실행하면, 콘솔에 '크루즈 컨트롤, 전후방 감지기, 전후방 카메라, 열선 시트, 스마트 키, 네비게이션, 에어백, 차선이탈 경보장치, 무선도어 잠금장치'가 출력된다.

     

    default 뜻은 말 그대로 '기본'이다.

    break문을 만나지 않는다면 switch문은 위에서부터 아랫 방향으로 모든 코드들을 실행시키기 때문에,

    이런 상황에서는 기본 옵션이 담길 동작은 가장 마지막에 작성해 줄 수밖에 없다.

     

    한 가지 예시를 더 들어보자.

    const gender = '남자';
    let msg = ''; 
    
    switch(gender) {
        case '남성':
        case '남자': // 여기서 부터 시작
        case '남':
            msg = '당신의 성별은 남성입니다.'; // 동작 수행
            break; // switch문 종료
        case '여성':
        case '여자':
        case '여':
            msg = '당신의 성별은 여성입니다.';
            break;
        default:
            msg = '성별을 다시 한 번 확인해 주세요';
    }
    
    console.log(msg); // '당신의 성별은 남성입니다.'

    switch문에서는 case문 별로 무조건 1가지 이상 코드를 작성할 필요는 없다.

    위 코드처럼 여러 case문을 겹쳐서 중복된 case를 구성할 수도 있다.

    여기서도 마찬가지로 case문은 그저 switch문 내부의 여러 동작들 중에서 가장 먼저 동작할 시작점을 찾는 기준이라는 점을 확인할 수 있다.

     

    주의사항

    가장 처음에도 언급했지만, 

    switch문은 어떤 값을 가진 대상을 두고 조건값 일치하는지를 확인하고 동작을 수행하는 방식이다.

    동등( == )이 아니라 일치( === )다. 

    즉, 대상과 조건값을 비교할 때 형 변환이 일어나지 않는다는 뜻이다.

    간혹 블로그에서 switch문을 if / else if / else문으로 변환하는 예시를 보여주면서

    조건식에서 동등(==) 비교로 변환하는 경우를 봤었는데, 동등 비교 예시는 옳지 않다.

    [JavaScript] 자바스크립트 형변환(Type Conversion) 이해하기 - 3에서 정리했듯이

    동등 비교는 형 변환을 일으킨다.

    let target = '1';
    
    switch(target) {
        case 1:
            console.log('target은 숫자형 1입니다.');
            break;
        default:
            console.log('target값을 다시 확인해 주세요.'); 
    }
    let target = 1;
    
    switch(target) {
        case '1':
            console.log('target은 문자열 1입니다.');
            break;
        default:
            console.log('target값을 다시 확인해 주세요.'); 
    }

    위 두 코드는 콘솔에 'target값을 다시 확인해 주세요.'가 출력된다.

    문자열 1이 숫자 1로, 혹은 숫자 1이 문자열 1로 형 변환되는 일은 없다는 뜻이다.

    let target = '1';
    
    switch(target) {
        case 1:
            console.log('target은 숫자형 1입니다.');
            break;
        case '1':
            console.log('target은 문자열 1입니다.');
            break;
        default:
            console.log('target값을 다시 확인해 주세요.'); 
    }

    switch문은 대상과 case의 조건값이 명확하게 일치하는지를 평가하기 때문에, 형 변환이 일어나지 않는다.

     

    마무리

    switch문은 조건식의 진위가 아니라, 조건값의 일치 여부를 평가하기 때문에,

    조금 넓은 범위의 조건에서 공통적인 동작들을 수행할 때는 불리한 단점이 있다.

    필요한 범위를 충족하는 조건값들을 하나하나 모두 명시해야 하는 번거로움 때문이다.

    상황에 따라서는 이러한 단점이 꽤나 치명적인데,

    개인적으로는 학습할 때 외에는 특별히 사용해 본 경험은 없는 것 같다.

     

    사실 그래서 별로 중요하게 생각하지 않고 가볍게 정리하려고 했는데

    작성하다 보니 생각보다 너무 길게 정리한 것 같지만,

    그래도 이번 기회를 통해 switch문에 대해서 조금 더 살펴볼 수 있게 되어서 만족스럽다.

    댓글

Designed by BigTop.