[궁금해서 찾아본] switch? 아뇨 그거 말구요

Hoon Kang·2023년 4월 6일
2

궁금해서 찾아본

목록 보기
3/3
post-thumbnail

멋사 5기 수업을 듣던 중...오늘은 자바스크립트 문법에서 switch에 대해서 배우게 되었다.
사실 블로그 포스팅을 안 한지 어언 1달..."글을 매일매일 쓰겠어!"라는 다짐은 URL을 입력하세요 포스팅을 작성하는 데 장장 4시간이 걸리는 것을 깨닫고 내던진지 오래였다.


안녕하세요? 능이버섯입니다.

하지만 switch? 이거라면 할 수 있어! 라는 생각이 들어서 오랜만에 키보드를 잡게 되었다.

잡설은 생략하고, 바로 알아보도록 하자.

조건문이란

먼저 swtich에 대해 이야기하기 전에, 조건문에 대해서 알아보도록 하자

if (조건식) {
  // 조건식이 참이면 이 코드를 실행한다.
} else {
  // 조건식이 거짓이면 이 코드를 실행한다.
}

너무 간단하다! 조건식이 참이라면 { } 내부의 코드를 실행하는 것, 그것이 조건문이다.
물론 사실 "참", "거짓"이라고 단순히 말하기에는 truthy(트루시; 참 같은 값)와 falsy(폴시; 거짓 같은 값)라는 말이 있지만, 그것까지 생각하면 머리가 아파지기도 하고, 오늘의 이야기 주제는 트루시와 폴시가 아니니 살짝쿵 넘어가도록 하자.

만약 조건이 두개라면, ifelse if로 조건을 나누어주면 된다.

if (조건식) {
  // 조건식이 참이면 이 코드를 실행한다.
} else if (조건식 2) {
  // 첫 번째 조건식이 거짓이면 조건식 2를 확인하고, 조건식 2가 참이라면 이 코드를 실행한다.
} else {
  // 둘 다 거짓이면? 이쪽입니다~
}

switch()

switch문도 이와 같이 조건을 나누어서 실행할 코드를 결정하지만, 조금 다르게 생겼다.

switch(x) {
  case 'value1':  // x가 value1이라면 실행
    ...
    [break]

  case 'value2':  // x가 value2라면 실행
    ...
    [break]

  default:       // x가 어떤 값에도 해당되지 않을 경우 실행
    ...
    [break]
}

switch문은 값을 받아와서 그 값을 기준으로 case의 조건들을 비교한다. 만약 일치하는 조건이 있다면 그 case 내부로 들어가 코드 블럭을 실행한다. default 문은 x가 어떤 case에도 해당하지 않을 때 실행된다. 이렇게 명시적으로 기본값을 알려줄 수 있다는 점에서 default 사용은 권장된다. 또한 각 case 내부의 구문에 break 키워드를 작성해 주어야 한다.

...왜?

fall-through

그것은 바로 오늘 이야기의 주제인 fall-through behavior(폴스루 현상) 때문이다.
switch() 문에서 각 케이스 별 코드 블럭의 마지막에 break 키워드를 작성하지 않는다면, fall-through(폴스루) 현상이 발생한다. 다음과 같은 코드를 살펴보자.

const expression = 10 - 5

switch (expression) {
  case 1:
    console.log("결괏값은 1입니다.")

  case 5:
    console.log("결괏값은 5입니다.")

  case 10:
    console.log("결괏값은 10입니다.")

  default:
    console.log("결괏값이 존재하지 않습니다.")
}

// 출력
// 결괏값은 5입니다.
// 결괏값은 10입니다.
// 결괏값이 존재하지 않습니다.

위와 같은 현상이 폴스루 현상이다. break 키워드를 사용하지 않았기 때문에, switch문은 expression의 case를 확인한 후 조건을 충족하는 case의 코드 블럭부터 마지막 case의 코드 블럭까지 순차적으로 실행한다.

따라서 break 키워드를 사용한다는 것은, siwtch 문에게 “폴스루를 하지 말고 여기서 멈춰라”라고 알려주는 것과 같다.

그렇다면 default는 break 키워드가 필수일까?

⇒ 정확히 이야기하자면, default의 위치가 어디냐에 따라 다르다.

만약 위의 코드와 같이 default가 가장 마지막에 위치한다면, default 내부에 break가 존재하지 않더라도 그 이후에 실행될 다른 case들이 없기 때문에 default 코드 블럭 하나만 실행된다.

⇒ 그래서 조금 더 정확히 말하자면, 마지막에 오는 case는 (default건 case건) break 키워드가 없어도 된다고 할 수 있을 것 같다.

fall-through의 활용법

const expression = 10 - 2

switch (expression) {
  case 2:
    console.log("결괏값이 8보다 작습니다.")
		break;

  case 5:
    console.log("결괏값은 8보다 작습니다.")
		break;

  case 8:
    console.log("결괏값은 8입니다.")
		break;

  default:
    console.log("결괏값이 존재하지 않습니다.")
}

// 출력
// 결괏값은 8입니다.

맨 처음 코드랑 비슷한 예제이다. 그런데 case 2:case 5:의 코드 블럭은 모두 “결괏값이 8보다 작습니다.”로 동일하다.

코드의 중복을 줄일 수 있는 방법이 있을까? 이때 빛을 발하는 것이 바로 폴스루이다.

const expression = 10 - 8

switch (expression) {
  case 2:

  case 5:
    console.log("결괏값은 8보다 작습니다.")
		break;

  case 8:
    console.log("결괏값은 8입니다.")
		break;

  default:
    console.log("결괏값이 존재하지 않습니다.")
}

// 출력
// 결괏값은 8보다 작습니다.

뭔가 잘못 작성된 구문 같지만, 올바르게 작동하는 구문이다. 한번 살펴보자.

  1. expression의 값은 2이고, switch문은 조건에 맞는 case를 탐색하기 시작한다.
  2. case 2: 에 먼저 도착했다.
    • 실행할 코드가 존재하지 않기 때문에, 어떤 것도 실행하지 않는다.
    • break 키워드도 없기 때문에, 폴스루 현상이 발생한다.
  3. 폴스루 현상으로 인해 case 5:로 이동한다.
    • console.log() 코드를 실행한다.
    • break 키워드를 발견했다. 와! 실행 종료!

이렇게 fall-through behavior를 활용하면 switch문의 가독성 문제와 코드 중복을 둘 다 해결할 수 있다.

레퍼런스

profile
세상의 모든 것들이 궁금한 개발자

1개의 댓글

comment-user-thumbnail
2023년 4월 6일

우와 해당 문법이 '왜' 저렇게 동작하는지에 대해 의문을 가지고 접근하신게 인상깊어요!
항상 아무 생각없이 사용했는데 덕분에 'fall-through'라는 개념을 정확하게 짚고 갑니다👏👏

답글 달기