본문 바로가기
Programming/JavaScript

조건문 if, switch case - [Javascript 입문 _6]

by Muko 2020. 4. 8.

8. 조건문

우리는 살면서 많은 선택을 하게 됩니다.
프로그래밍 또한 마찬가지 입니다. 코드를 작성하면서 조건에 따라 진행하는 과정이 달라지게끔 구현해야하는 경우가 많습니다. 이럴 때 프로그래밍에서는 조건문이라는 문법을 사용합니다.

자바스크립트에서 조건문은 크게 세가지 입니다.

  • if, else if, else
  • switch, case
  • ? (삼항 연산자)
    하나씩 살펴보도록 하겠습니다.

 

8-1. if와 else

if문은 if ( 조건... )과 같은 형식으로 사용합니다. 괄호 안에 들어있는 조건을 평가한 뒤에, 그 결과를 불린형으로 변환한 값이 true이면 그 뒤에 중괄호 안에 코드를 실행하고, false이면 실행하지 않습니다. 선택지가 true일 경우와 false일 경우 두 갈래로 나뉘는 거죠.

불린형으로의 변환된다는 것은 결국 조건에 해당하는 내용이 truthy인가, falsy인가에 대한 내용입니다. truthy에 해당한다면 불린형으로 변환되었을 때 true가 되는 것이죠. 이 내용은 불리언(boolean)과 연산자 챕터에서 다루었습니다.

위의 코드에서 if문을 두 개를 사용했습니다. myAge가 30 미만일 경우, 그리고 30 이상일 경우에 대해서 코드를 작성했습니다. 지금 myAge는 30이라는 값으로 초기화되었으니 위의 조건문에서는 false값이 되어 실행되지 않고, 아래 조건문에서는 true값이 반환되어 '계란 한판을 넘으셨군요! 라는 알림과 '나이와 상관없이 멋있습니다.'라는 알람이 뜨게됩니다.

여기서 조건문 뒤에 실행되는 코드가 1줄일 경우에는 위의 조건문 처럼 중괄호를 생략할 수 있지만, 여러 줄의 코드를 작성할 경우에는 반드시 중괄호를 작성해야 합니다. 하지만 내가 쓴 코드를 다른 사람이 읽는 것을 항상 고려해서 읽기 좋은 코드를 작성해야합니다. 그래서 { }를 사용해서 조건문 뒤에 실행될 코드를 감싸는 것을 추천합니다. 읽기 좋은 코드를 보통 가독성이 높은 코드라고 표현합니다.

만약 조건이 다음과 같이 세세하게 나뉘게 된다면 어떨까요?

결과는 C grade라는 알람창이 뜨게됩니다.

 

8-2. else

방금 작성했던 코드를 else를 적용하면 더욱 심플하게 작성할 수 있습니다. else는 아래와 같이 if 조건에서 false 나왔을 때에 동작하는 문법입니다.

if (조건) {
  // 참일 때 실행되는 코드
} else {
  // 조건이 거짓일 때 실행되는 코드
}

이 코드는 두 개의 분기(참 혹은 거짓)을 다룰 수 있는데, if와 else를 동시에 쓰면 여러 개의 분기(조건)을 사용할 수 있게 됩니다.

if (조건1) {
  // 조건1이 참일 때 실행
} else {
  // 조건1이 거짓일 때 실행
  if (조건2) {
    // 조건2가 참일 때 실행
  } else {
    // 조건2가 거짓일 때 실행
  }
}

여러개의 조건을 이렇게 if와 else로 작성하기는 했는데, 전혀 깔끔하지 않습니다. 코드 가독성이 떨어지죠.

그런데 위에서 말씀드렸듯이 if문 뒤에 코드가 한 줄일 경우 중괄호를 생략할 수 있다고 설명드렸습니다. 여기서 한 줄이라는게 코드 상에서 정확하게 한 줄을 의미하는 것이 아니라, 한 개의 동작 단위(코드 블록 혹은 세미콜론 하나로 이루어진)라고 생각하시면 됩니다. if문을 작성할 때 중괄호로 감싸게 되는데, 이러한 코드 블록은 한 개의 동작 단위로 처리되어 중괄호가 생략 가능합니다. 이 특징을 살려서 작성하면 다음과 같습니다.

if (조건1) {
  // 조건1이 참일 때 실행
} else if (조건2) {
  // 조건1이 거짓이고 조건2가 참일 때 실행
} else {
  // 조건1, 조건2가 거짓일 때 실행
}

이 코드가 흔히 프로그래밍 언어에서 사용되는 else if문 입니다. 저도 처음에는 if, else if, else 이렇게 세 개인 줄 알고 당연하다는 듯이 사용했었는데, 사실은 if와 else 두개로 이루어진 문법입니다.

이렇게 깔끔하게 예시 코드를 다시 작성해보면 다음과 같습니다.

const myScore = 78;

if (myScore > 90) {
  alert('A grade');
} else if (myScore > 80) {
  alert('B grade');
} else if (myScore > 70) {
  alert('C grade');
} else {
  alert('F grade');
}

 

8-3. switch, case

위의 코드를 if문이 아니라 switch, case문을 이용해서 같은 동작을 하게끔 구현하는 것이 가능합니다. switch case 문은 다음과 같이 사용합니다.

switch (입력값) {
  case 조건1:
    실행1;
    break;
  case 조건2:
    실행2;
    break;
  case 조건3:
  case 조건4:
  case 조건5:
    실행3;
    break;
  default:
    실행4;
}

switch 문 옆의 괄호 안에는 비교대상이 되는 값 혹은 변수를 넣게되고, 각 case 옆에는 조건과 콜론( : )을 붙이게 됩니다. 그리고 각 case 아래에 실행하고자 하는 코드를 작성하고, 그 실행 코드 이후에 다른 것을 실행하지 않으려면 break; 를 작성하시면 됩니다. 코드는 대부분의 경우 위에서부터 내려오면서 동작하기 때문에 만약 입력값이 조건1에 부합하고, 실행1 아래에 break가 없다면 그 아래에 있는 실행2도 동작하는 구조입니다.

8-2의 마지막 예제를 switch case 문으로 바꿔보겠습니다.

const myScore = 78;

switch (myScore) {
  case 100:
  case 99:
  case 98:
  case 97:
  case 96:
  case 95:
  case 94:
  case 93:
  case 92:
  case 91:
    alert('A grade');
    break;
  case 90:
  case 89:
  case 88:
  case 87:
  ....
  case 81:
    alert('B grade');
    break;
  case 80:
  ...
  case 71:
    alert('C grade');
    break;
  default:
    alert('F grade');
}

이렇게 예제를 바꿔보니 동일하게 동작하는 것은 알겠는데, 굳이 사용해야하나 싶은 생각이 들지 않나요? 맞습니다. 어떤 조건에 대해서 대소비교와 관련된 분기가 이루어져야 하는 경우는 위와 같이 switch case문을 사용하면 매우 비효율적입니다. 코드를 작성하는데 누가 저런 노가다성 코드를 좋아하겠어요? 손 아프잖아요. 그럼 switch case를 언제 사용하면 유용한지 의문이 들겁니다. 정답은 바로 대소비교가 아니라 말그대로 '비교'일 경우입니다. 예제로 보시죠.

const myType = '학생';

switch (myType) {
  case '학생':
    alert('학생 할인 대상입니다');
    break;
  case '성인':
    alert('할인 대상이 아닙니다');
    break;
  case '어르신':
    alert('어르신은 무료로 이용하시면 됩니다');
    break;
 }

코드를 살펴보면 myType이라는 변수에 '학생'이라는 값으로 초기화했고, switch 문에서 myType을 검사하고 있습니다. if 문에서 사용하려면 myType === '학생' 이런식으로 조건을 작성해야 하지만, switch case 문에서는 간단하게 비교값만 작성하면 됩니다.

더 간단한 예제를 살펴볼까요?

const myOrder = 4;

switch (myOrder) {
  case 1:
    alert('첫 번째 순서입니다.');
    break;
  case 2:
    alert('두 번째 순서입니다.');
    break;
  case 3:
    alert('세 번째 순서입니다.');
    break;
  case 4:
    alert('네 번째 순서입니다.');
    break;
  default:
    alert('마감되었습니다. 다음에 다시 오세요');
}

숫자의 경우에도 위와 마찬가지로 비교 대상이 되는 정수 값만 사용하면 됩니다. 단 여기서 주의하셔야 할 점은 정수만 사용 가능하다는 점입니다. 소수값을 사용하게 되면 원하는 결과를 얻지 못할 수도 있으니 주의하세요!

 

8-4. 삼항 연산자 '?'

조건문을 이용하면 위와 같은 프로그램을 구현하는 것이 가능합니다. 그런데 위와 같이 2개의 분기(true 혹은 false에 해당하는 결과)만을 사용하는 코드일 경우에 저번 시간에 배웠던 삼항 연산자를 사용해서 더 깔끔하게 작성하는 것이 가능합니다.

위의 코드는 canVote라는 함수에 나이를 파라미터로 넘겨서 동일한 결과를 가지게끔 작성했습니다. 이 코드에서 이해하셔야 할 점은 다음과 같습니다.

  • 변수 스코프(범위) : 위의 두 줄에 선언한 stringCan과 stringCanNot은 현재 가장 밖의 범위에 존재합니다. 그래서 함수표현식을 이용해서 작성한 canVote 함수 안에서도 사용 가능합니다. 만약 canVote안에 다른 변수가 선언되었다면, 그 변수는 함수 밖에서 사용하지 못하게 됩니다. 이 개념에 대해서 이해가 잘 되지 않으신다면 전역 변수, 지역 변수라는 키워드로 검색하시면 많은 자료를 찾아보실 수 있습니다.
  • 화살표 함수 : ES2015(ES6)에서 적용된 문법으로 함수를 심플하게 작성 가능하게끔 만들어주는 문법입니다. canVote함수는 age라는 인자를 가지고 그 인자 값에 따라 동작이 달라지는 함수입니다.
  • 함수의 동작 시기 : 함수는 위와 같이 선언되었을 때 동작하는 것이 아니라, 호출되었을 때 동작합니다.

만약 함수에 대해 이해가 잘 가지 않으시는 분은 전에 작성한 함수 포스팅을 참고해주세요.

그런데 사실 삼항 연산자를 위의 예시와 같이 사용하는 것은 그리 좋은 습관은 아닙니다. 우리는 코드를 읽을 때 수평보다는 수직으로 움직이는 것을 편하게 느낍니다. 그래서 길게 옆으로 늘어진 코드보다는 여러 줄로 나뉘어져 있는 코드 블록이 읽기가 더 쉽죠. 삼항 연산자라는 문법이 만들어진 이유는 if대신 사용하라는 의도가 아니라, 조건에 따라 반환 값을 다르게 하려는 목적으로 만들어졌습니다. 이게 무슨 차이인지 감이 안오시죠? 코드로 한 번 보시죠.

이렇게 여러 분기를 만들 때는 if else를 이용한 코드가 훨씬 이해하기도 편하고, 가독성도 좋습니다. 삼항 연산자를 사용하기 좋은 경우는 다음과 같습니다.

const myAge = 18;
const canVote = (myAge >= 18) ? '투표권 O' : '투표권 X';

// 연산자 우선순위에 따라 비교 연산인 myAge >= 18이 먼저 실행됩니다.
// 그래서 조건문에 괄호를 생략할 수 있지만, 괄호가 있는게 가독성이 더 좋습니다.
const canVote2 = myAge >= 18 ? '투표권 O' : '투표권 X';

// 조건에 따른 반환값이 불리언(true, false)일 경우 다음과 같이 생략 가능합니다.
const canVote3 = myAge >= 18;

이론만 배우면 재미가 없습니다. 간단한 코드를 하나 둘씩 짜다보면서 재미를 느끼시길 바라는 마음에서 다음 시간에는 지금까지 배운 내용들을 이용해서 간단한 토이 프로젝트를 만들어 보겠습니다.

댓글8