본문으로 건너뛰기
Advertisement

3.1 조건문

조건문이란?

조건문은 주어진 조건에 따라 다른 코드 블록을 실행하는 제어 구조입니다. JavaScript는 if/else, switch, 삼항 연산자를 지원합니다.


if / else 문

기본 구조

const temperature = 25;

if (temperature > 30) {
console.log("덥네요!");
} else if (temperature > 20) {
console.log("적당한 날씨입니다.");
} else if (temperature > 10) {
console.log("쌀쌀합니다.");
} else {
console.log("춥네요!");
}
// "적당한 날씨입니다."

중괄호 생략 (권장하지 않음)

// 한 줄일 때 중괄호 생략 가능하지만...
if (condition) doSomething();

// 중괄호 없으면 버그 발생 가능!
if (condition)
console.log("첫 번째");
console.log("두 번째"); // 조건과 무관하게 항상 실행!

// 항상 중괄호 사용 권장
if (condition) {
console.log("첫 번째");
}
console.log("두 번째"); // 명확하게 조건 밖

복합 조건

const age = 22;
const hasID = true;

// AND: 모두 참이어야
if (age >= 19 && hasID) {
console.log("입장 가능합니다.");
}

// OR: 하나만 참이어도
const isWeekend = true;
const isHoliday = false;

if (isWeekend || isHoliday) {
console.log("쉬는 날!");
}

// NOT: 부정
const isLoggedIn = false;
if (!isLoggedIn) {
console.log("로그인이 필요합니다.");
}

switch 문

여러 가지 경우를 비교할 때 if-else 체인보다 가독성이 좋습니다.

기본 구조

const day = "월요일";

switch (day) {
case "월요일":
case "화요일":
case "수요일":
case "목요일":
case "금요일":
console.log("평일입니다.");
break;
case "토요일":
case "일요일":
console.log("주말입니다!");
break;
default:
console.log("알 수 없는 요일");
}

fall-through 주의

const grade = "B";
let message;

switch (grade) {
case "A":
message = "최우수";
break; // break 없으면 다음 case로 계속!
case "B":
message = "우수";
break;
case "C":
message = "보통";
break;
default:
message = "기타";
}

// 의도적 fall-through 활용
const month = 2;
let days;
switch (month) {
case 2:
days = 28;
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
default:
days = 31;
}

return으로 switch 정리

function getDayType(day) {
switch (day) {
case "토요일":
case "일요일":
return "주말";
default:
return "평일";
}
}

console.log(getDayType("토요일")); // "주말"
console.log(getDayType("월요일")); // "평일"

삼항 연산자 (Ternary Operator)

간단한 조건 표현에 사용합니다.

// 기본 구조: 조건 ? 참일때 : 거짓일때
const age = 18;
const status = age >= 19 ? "성인" : "미성년자";
console.log(status); // "미성년자"

// 함수 반환값
function getDiscount(isMember) {
return isMember ? 0.2 : 0.05;
}

// 템플릿 리터럴에서
const score = 85;
const result = `점수: ${score}${score >= 60 ? "합격" : "불합격"}`;
console.log(result); // "점수: 85 — 합격"

// 중첩 삼항 (가독성 주의)
const grade = score >= 90 ? "A"
: score >= 80 ? "B"
: score >= 70 ? "C"
: "F";

단락 평가 패턴

논리 연산자를 이용한 조건부 실행 패턴입니다.

// && 패턴: 조건이 true일 때만 실행
const isAdmin = true;
isAdmin && console.log("관리자 메뉴 표시");

// 조건부 객체 프로퍼티 추가
const includeAdmin = true;
const menuItems = [
"홈",
"프로필",
includeAdmin && "관리자", // false면 이 항목 제외 (하지만 false가 배열에 들어감!)
].filter(Boolean); // false/null/undefined 제거

// || 패턴: 기본값
const userName = "" || "익명 사용자";
const port = process.env.PORT || 3000;

// ?? 패턴: null/undefined일 때만 기본값
const config = userConfig ?? defaultConfig;
const timeout = options.timeout ?? 5000;

조기 반환 (Early Return) 패턴

중첩을 줄이고 코드를 평탄화하는 핵심 패턴입니다.

// 나쁜 예: 과도한 중첩
function processUser(user) {
if (user) {
if (user.isActive) {
if (user.hasPermission) {
// 실제 처리 코드
return doProcess(user);
} else {
return "권한 없음";
}
} else {
return "비활성 사용자";
}
} else {
return "사용자 없음";
}
}

// 좋은 예: 조기 반환으로 평탄화
function processUser(user) {
if (!user) return "사용자 없음";
if (!user.isActive) return "비활성 사용자";
if (!user.hasPermission) return "권한 없음";

// 실제 처리 코드 (주요 로직이 명확하게 보임)
return doProcess(user);
}

가드 패턴

함수 입력 유효성 검사에 사용합니다.

function divide(a, b) {
// 가드: 잘못된 입력을 먼저 처리
if (typeof a !== "number" || typeof b !== "number") {
throw new TypeError("숫자만 입력하세요");
}
if (b === 0) {
throw new Error("0으로 나눌 수 없습니다");
}

return a / b;
}

// 실전: API 핸들러
async function getUserById(req, res) {
const { id } = req.params;

if (!id) return res.status(400).json({ error: "ID가 필요합니다" });

const user = await db.findUser(id);
if (!user) return res.status(404).json({ error: "사용자를 찾을 수 없습니다" });

if (!user.isActive) return res.status(403).json({ error: "비활성 계정" });

res.json(user);
}

switch vs if-else 선택 기준

// switch가 적합한 경우: 단일 변수의 다양한 값 비교
function getStatusText(statusCode) {
switch (statusCode) {
case 200: return "OK";
case 201: return "Created";
case 400: return "Bad Request";
case 401: return "Unauthorized";
case 404: return "Not Found";
case 500: return "Internal Server Error";
default: return "Unknown";
}
}

// if-else가 적합한 경우: 범위 비교, 복잡한 조건
function categorize(score) {
if (score >= 90) return "A";
if (score >= 80) return "B";
if (score >= 70) return "C";
if (score >= 60) return "D";
return "F";
}

// 객체 매핑이 더 나을 때도 있음 (switch 대체)
const statusMessages = {
200: "OK",
404: "Not Found",
500: "Server Error",
};
const message = statusMessages[code] ?? "Unknown";

고수 팁

조건 단순화: 복잡한 조건을 변수로

// 나쁜 예: 조건이 길고 의미 파악 어려움
if (user.age >= 19 && user.isActive && !user.isBanned && user.subscription === "premium") {
showPremiumContent();
}

// 좋은 예: 의도를 이름으로 표현
const isAdult = user.age >= 19;
const isEligible = user.isActive && !user.isBanned;
const isPremium = user.subscription === "premium";

if (isAdult && isEligible && isPremium) {
showPremiumContent();
}

전략 패턴으로 조건문 대체

// 많은 조건이 있을 때 전략 패턴이 깔끔
const discountStrategies = {
vip: (price) => price * 0.7,
member: (price) => price * 0.9,
student: (price) => price * 0.8,
guest: (price) => price,
};

function calculatePrice(price, userType) {
const strategy = discountStrategies[userType] ?? discountStrategies.guest;
return strategy(price);
}

console.log(calculatePrice(10000, "vip")); // 7000
console.log(calculatePrice(10000, "student")); // 8000
console.log(calculatePrice(10000, "unknown")); // 10000
Advertisement