LHJ

I'm a FE developer.

4.2.5 switch 문

19 Apr 2020 » js_lj

if … else 문은 두 가지 중 하나를 선택하지만, switch 문은 조건 하나로 여러 가지 중 하나를 선택할 수 있습니다.
따라서 참 같은 값/거짓 같은 값보다는 다양하게 나뉘는 조건을 사용합니다.
switch 문의 조건은 값으로 평가할 수 있는 표현식 입니다.
switch 문의 문법은 다음과 같습니다.

switch (expression) {
	case value1 :
		// expression을 평과한 결과가 value1 일 때 실행됩니다.
		[break;]
	case value2 :
		// expression을 평가한 결과가 value2일 때 실행됩니다.
		[break;]
		...
	case valueN :
		// expression을 평가한 결과가 valueN일 때 실행됩니다.
		[break;]
	default:
		// expression을 평가한 결과에 맞는 것이 없을 때 실행됩니다.
		[break;]
}

자바스크립트는 expression을 평가하고 그에 일치하는 첫 번째 case를 찾아서 break, return, continue, throw를 만나거나 swith 문이 끝날 때까지 문을 실행합니다.

return과 continue, throw는 나중에 설명합니다.
복잡해 보이나요?
당신만 그렇게 느끼는 건 아닙니다.
switch 문은 그 미묘한 성격 때문에 실수를 초래한다는 비판을 받고 있습니다.
초보 프로그래머는 switch 문을 쓰지 말라는 조언을 듣기도 합니다.
필자는 switch 문을 적재적소에 쓰기만 하면 매우 유용한 도구라고 생각합니다.
물론, 모든 도구가 그렇듯 주의하는 습관을 들여야 하고 알맞은 상황에 써야 합니다.

아주 단순한 예제부터 시작해 봅시다.
토마스가 숫자에 대한 미신도 갖고 있다면 switch 문을 써서 토마스의 미신을 존중하도록 처리할 수 있습니다.

switch (totalBet) {
	case 7:
		totalBet = funds;
		break;
	case 11:
		totalBet = 0;
		break;
	case 13:
		totalBet = 0;
		break;
	case 21:
		totalBet = 21;
		break;
}

지금까지는 아주 단순합니다.
토마스는 주머니에서 꺼낸 돈이 11이나 13펜스면 돈을 걸지 않습니다.
하지만 13은 11보다 훨씬 불길한 숫자라서, 돈을 걸지 않는 것으로는 모자라고 1펜스를 기부해야 한다면 어떻게 해야 할까요?
switch 문을 다음과 같이 바꾸면 됩니다.

switch(totalBet) {
	case 7:
		totalBet = funds;
		break;
	case 13:
		funds = funds - 1; // 1펜스를 기부합니다!
	case 11: 
		totalBet = 0;
		break;
	case 21:
		totalBet = 21;
		break;
}

totalBet이 13이면 1펜스를 기부합니다.
그리고 break 문이 없으므로 다음 case 11로 넘어가서 totalBet을 0으로 만듭니다.
이 코드는 유효한 자바스크립트이며, 우리가 원하는 일을 정확히 수행합니다.
하지만 약점도 있습니다.
이 코드는 정확한데도 불구하고 실수처럼 보입니다.
동료가 이 코드를 보고 break 문을 깜빡 잊은 거로 생각할 수도 있습니다.
그 동료는 break 문을 추가할 테고, 코드는 원하는 대로 동작하지 않게 될 겁니다.
break 없는 case 절이 장점보다는 단점이 더 많다고 생각하는 사람들이 많으니, 이 기능을 활용하고 싶다면 항상 주석을 남겨서 의도적으로 break 문을 생략했다는 것을 명확히 하십시오.

default 는 특별한 경우입니다.
default 절은 일치하는 case 절이 없을 때 실행됩니다.
default 절은 필수는 아니지만, 보통 땐 마지막에 사용합니다.

switch(totalBet) {
	case 7:
		totalBet = funds;
		break;
	case 13:
		funds = funds - 1; // 1 펜스를 기부합니다!
	case 11:
		totalBet = 0;
		break;
	case 21:
		totalBet = 21;
		break;
	default:
		console.log("No superstition here!");
		break;
}

default 뒤에는 case가 없으므로 break 문이 없어도 되지만, 항상 break 문을 사용하는 게 좋은 습관입니다.
언제든 break 문을 주석 처리할 수 있으므로, 설령 break 없는 case 절을 사용하더라도 항상 break 문을 쓰는 습관을 들여야 합니다.
break 문이 필요한데도 쓰지 않았다면 매우 찾기 어려운 버그가 생길 수 있습니다.
이 규칙의 예외는 switch 문을 함수 안에서 쓸 때뿐입니다.
return 문은 즉시 함수를 빠져나가므로 break 문 대신 쓸 수 있습니다.

function adjustBet (totalBet, funds) {
	switch(totalBet) {
		case 7:
			return funds;
		case 13:
			return 0;
		default:
			return totalBet;
	}
}

자바스크립트는 공백이 몇 칸이든 신경 쓰지 않으므로 break나 return 문을 실행할 문과 같은 행에 넣으면 switch 문을 더 간결하게 만들 수 있습니다.

switch (totalBet) {
	case 7: totalBet = funds; break;
	case 11: totalBet = 0; break;
	case 13: totalBet = 0; break;
	case 21: totalBet = 21; break;
}

11펜스와 13펜스일 때 같은 일을 하지만, 여기서는 break 없는 case 절을 쓰지 않았습니다.
이렇게 switch 문을 줄바꿈 없이 쓸 때는 case마다 실행문이 하나씩 있고, break 없는 case 절을 쓰지 않아야 의도가 명확하게 드러납니다.

switch 문은 표현식 하나로 여러 가지 옵션 중에서 하나를 선택해야 할 때 아주 유용합니다.
그렇긴 하지만, 9장에서 동적 디스패치(dynamic dispatch) 에 대해 배우고 나면 switch 문을 그리 많이 쓰지는 않게 될 겁니다.