조건문과 논리 연산자 — 단축 평가, Nullish Coalescing, Optional Chaining
자바스크립트의 논리 연산자는 단순히
true/false를 반환하는 게 아닙니다. 단축 평가(short-circuit evaluation) 를 이해하면 코드를 훨씬 간결하게 쓸 수 있고,??와?.는 모던 자바스크립트의 필수 문법입니다.
단축 평가 (Short-Circuit Evaluation)
&& (논리 AND)
&&는 첫 번째 falsy 값을 반환하고, 모두 truthy면 마지막 값을 반환합니다.
// falsy 값을 만나면 즉시 반환
console.log(0 && "hello"); // 0
console.log("" && "hello"); // ""
console.log(null && "hello"); // null
// 모두 truthy면 마지막 값 반환
console.log("a" && "b" && "c"); // "c"
// 실전: 조건부 실행
const isAdmin = true;
isAdmin && showAdminPanel(); // isAdmin이 true일 때만 실행
|| (논리 OR)
||는 첫 번째 truthy 값을 반환하고, 모두 falsy면 마지막 값을 반환합니다.
// truthy 값을 만나면 즉시 반환
console.log("hello" || "default"); // "hello"
console.log(0 || "default"); // "default"
// 모두 falsy면 마지막 값 반환
console.log(0 || "" || null); // null
// 실전: 기본값 설정
const name = userInput || "익명";
|| 의 함정
// 문제: 0과 빈 문자열도 falsy로 취급됨
const count = 0;
const result = count || 10;
console.log(result); // 10 — 0이 유효한 값인데 무시됨!
const text = "";
const display = text || "기본 텍스트";
console.log(display); // "기본 텍스트" — 빈 문자열이 의도된 값일 수 있음
이 문제를 해결하기 위해 Nullish Coalescing 연산자 가 등장했습니다.
?? (Nullish Coalescing)
??는 왼쪽 값이 null 또는 undefined일 때만 오른쪽 값을 반환합니다.
// null과 undefined만 걸러냄
console.log(0 ?? 10); // 0 — 0은 null/undefined가 아님
console.log("" ?? "기본"); // "" — 빈 문자열도 유효
console.log(false ?? true); // false — false도 유효
console.log(null ?? "기본"); // "기본"
console.log(undefined ?? 10); // 10
|| vs ?? 비교
const config = { timeout: 0, retries: null };
// || 사용 — 0이 무시됨
config.timeout || 3000; // 3000 (의도치 않음)
// ?? 사용 — 0은 유효한 값
config.timeout ?? 3000; // 0 (정확한 동작)
config.retries ?? 3; // 3 (null이니까 기본값)
면접에서 "||와 ??의 차이"를 물어보면, ||는 **falsy 체크 **, ??는 nullish 체크 라고 답하면 됩니다.
?. (Optional Chaining)
중첩 객체의 프로퍼티에 안전하게 접근합니다.
const user = {
name: "정훈",
address: {
city: "서울",
},
};
// 기존 방식 — 장황함
const zipCode = user && user.address && user.address.zipCode;
// Optional Chaining — 간결
const zipCode2 = user?.address?.zipCode;
console.log(zipCode2); // undefined (에러 없이)
다양한 활용
// 메서드 호출
const result = user.getName?.(); // getName이 없으면 undefined
// 배열 접근
const first = arr?.[0]; // arr이 null/undefined면 undefined
// 동적 프로퍼티
const value = obj?.[dynamicKey];
// 함수 호출
callback?.(); // callback이 있을 때만 실행
??와 ?. 조합
// API 응답에서 안전하게 값 추출 + 기본값 설정
const response = {
data: {
user: null,
},
};
const userName = response?.data?.user?.name ?? "익명";
console.log(userName); // "익명"
??= (Nullish 할당)
let config = { timeout: null, retries: 3 };
// null이면 할당
config.timeout ??= 5000;
console.log(config.timeout); // 5000
// null/undefined가 아니면 유지
config.retries ??= 10;
console.log(config.retries); // 3
// ||= 도 있음 (falsy 할당)
let count = 0;
count ||= 10;
console.log(count); // 10 — 0이 falsy라서 할당됨
count = 0;
count ??= 10;
console.log(count); // 0 — 0은 nullish가 아님
falsy 값 총정리
// 자바스크립트의 falsy 값 (7개)
if (!false) console.log("false");
if (!0) console.log("0");
if (!(-0)) console.log("-0");
if (!"") console.log("빈 문자열");
if (!null) console.log("null");
if (!undefined) console.log("undefined");
if (!NaN) console.log("NaN");
// 나머지는 전부 truthy
if ({}) console.log("빈 객체도 truthy"); // truthy
if ([]) console.log("빈 배열도 truthy"); // truthy
if ("0") console.log("문자열 0도 truthy"); // truthy
빈 객체 {}와 빈 배열 []이 truthy라는 점은 면접에서 자주 출제됩니다.
실전 패턴 모음
// 1. 조건부 프로퍼티 추가
const user = {
name: "정훈",
...(isAdmin && { role: "admin" }),
};
// 2. 환경 변수 기본값
const port = process.env.PORT ?? 3000;
// 3. API 응답 안전 처리
const items = response?.data?.items ?? [];
// 4. 메서드 존재 확인 후 호출
element?.addEventListener?.("click", handler);
**기억하기 **:
||는 falsy 전부를 걸러내고,??는 null과 undefined만 걸러냅니다.?.는 중첩 접근의 안전 장치입니다. 이 세 가지를 조합하면 방어적 코드를 간결하게 작성할 수 있습니다.
댓글 로딩 중...