티스토리 뷰
Optional Chaining과 Nullish Coalescing: 런타임 에러를 방어하는 우아한 코드 설계
미니임 2026. 3. 3. 23:09
현대 웹 애플리케이션은 수많은 외부 API와 복잡한 데이터 구조 위에서 동작합니다. 프런트엔드 개발자라면 누구나 한 번쯤 Uncaught TypeError: Cannot read property '...' of undefined라는 공포의 에러 메시지를 마주해 보셨을 겁니다.
데이터가 항상 존재할 것이라는 낙관적인 가정은 곧 서비스의 장애로 이어집니다. 과거에는 이를 방지하기 위해 장황한 if 문이나 논리 연산자(&&)를 중첩해서 사용했지만, **ES2020(ES11)**에서 등장한 **Optional Chaining(?.)**과 **Nullish Coalescing(??)**은 코드의 가독성을 비약적으로 높이면서도 안전한 방어 코드를 작성할 수 있게 해주었습니다.
1. Deep Dive: 왜 이 기술이 필요한가?
존재하지 않는 데이터에 대한 접근
자바스크립트에서 null이나 undefined에 마침표(.)를 찍어 속성에 접근하려고 하면 스크립트는 즉시 중단됩니다. 이를 방지하기 위한 전통적인 방식은 다음과 같았습니다.
// 고전적인 방어 코드 (AND 연산자 활용)
const zipCode = user && user.address && user.address.zipCode;
데이터의 깊이(Depth)가 깊어질수록 코드는 우측으로 길어지고, 읽기 힘들어집니다. Optional Chaining은 이 과정을 "단락 평가(Short-circuiting)" 방식으로 해결합니다.
0과 빈 문자열('')의 딜레마
기존에 기본값(Default value)을 설정할 때 자주 쓰던 OR 연산자(||)는 치명적인 약점이 있습니다. 0, "", false 같은 값들을 모두 Falsy로 취급하여 무시해버린다는 점입니다.
- 사용자의 점수가 0점일 때, score || 100을 실행하면 결과는 100이 됩니다.
- Nullish Coalescing은 오직 null과 undefined만 걸러냄으로써 개발자의 의도를 정확히 반영합니다.
비유로 이해하기: 안전한 배송 시스템
- Optional Chaining(?.): 택배 기사님이 아파트 동·호수를 확인하는데, 만약 'A동' 자체가 없다면 더 이상 집 호수를 찾지 않고 즉시 배송 불가(undefined) 판정을 내리고 복귀하는 것과 같습니다.
- Nullish Coalescing(??): 고객이 옵션을 선택하지 않았을 때만 기본 사은품을 넣는 것입니다. 고객이 '0번 옵션'을 선택했다면, 그것도 선택한 것이니 사은품을 주지 않고 0번을 그대로 배송합니다.
2. Creative Hands-on: 실전 이커머스 대시보드 로직
단순한 예제 대신, 다양한 상태를 가진 주문 데이터에서 통계 값을 추출하는 실무형 코드를 살펴보겠습니다.
/**
* 이커머스 주문 데이터를 처리하여 요약 정보를 반환하는 함수
*/
function getOrderSummary(orderData) {
// 1. Optional Chaining으로 중첩된 객체 안전하게 접근
// 2. Nullish Coalescing으로 수치 데이터 기본값 설정 (0점이나 빈 문자열 보존)
const customerName = orderData?.customer?.profile?.name ?? "비회원";
const shippingFee = orderData?.logistics?.fee ?? 0; // 배송비가 0원일 때 ||를 쓰면 0을 무시함
const couponDiscount = orderData?.payment?.discount?.amount ?? 0;
// 메서드 호출 시에도 안전하게 사용 가능
const formattedDate = orderData?.getTimestamp?.() ?? "날짜 정보 없음";
const items = orderData?.items ?? [];
const itemCount = items.length;
return {
customerName,
shippingFee,
couponDiscount,
itemCount,
formattedDate
};
}
// 실전 데이터 케이스
const rawOrder = {
customer: { profile: { name: "Aiden" } },
logistics: { fee: 0 }, // 무료 배송 케이스
payment: { discount: { amount: null } },
// getTimestamp는 누락됨
};
const summary = getOrderSummary(rawOrder);
console.log(`고객명: ${summary.customerName}`); // Aiden
console.log(`배송비: ${summary.shippingFee}원`); // 0 (||를 썼다면 undefined나 0이 아닌 다른 값이 나올 위험)
console.log(`할인액: ${summary.couponDiscount}원`); // 0
console.log(`상품 수: ${summary.itemCount}개`); // 0
console.log(`주문일: ${summary.formattedDate}`); // 날짜 정보 없음
🛠 Troubleshooting Tip
orderData?.customer?.profile.name 처럼 중간까지만 체이닝을 걸고 마지막에 실수로 마침표를 찍으면, profile이 없을 때 여전히 에러가 발생합니다. **"불확실한 모든 단계에 ?.를 붙이되, 반드시 존재해야 하는 값에는 .을 써서 의도를 명확히 하는 것"**이 디버깅에 유리합니다.
3. Trade-offs: 고려해야 할 사항
강력한 도구지만 남용은 금물입니다.
- 남용 시의 위험성 (Silent Fail): 모든 곳에 ?.를 붙이면 데이터 구조가 잘못되어도 에러가 발생하지 않고 조용히 undefined를 반환합니다. 이는 나중에 원인을 알 수 없는 버그(Logic Error)를 추적하기 어렵게 만듭니다.
- 할당 연산자 사용 불가: obj?.prop = 'value'와 같이 왼쪽에 위치하여 값을 할당하는 용도로는 사용할 수 없습니다.
- 브라우저 호환성: 대부분의 현대 브라우저는 지원하지만, 구형 환경이나 IE를 지원해야 한다면 Babel과 같은 트랜스파일러 설정이 필수적입니다.
결론 및 제언
Optional Chaining과 Nullish Coalescing은 단순히 코드를 짧게 만드는 '문법적 설탕(Syntactic Sugar)' 이상의 가치를 지닙니다. 이는 개발자가 데이터의 불확실성을 인정하고, 그 예외 케이스를 어떻게 처리할지 선언적으로 기술하게 해줍니다.
'Frontend > JAVASCRIPT' 카테고리의 다른 글
| 현대 자바스크립트의 심장, ES Modules(ESM) 완벽 가이드: import와 export (0) | 2026.03.03 |
|---|---|
| 사용자 경험과 비용을 동시에 잡는 기술: 디바운스와 쓰로틀링 Deep Dive (0) | 2026.03.03 |
| 완벽한 에러 핸들링을 위한 전략: try...catch 그 이상의 실무 패턴 (0) | 2026.03.03 |
| 클래스 없는 상속의 마법, 자바스크립트 프로토타입 완벽 이해하기 (0) | 2026.03.02 |
| 브라우저의 기억 장치, LocalStorage 완벽 가이드: 데이터 지속성의 핵심 (0) | 2026.03.02 |
- Total
- Today
- Yesterday
- java
- MSA
- 웹기초
- HTML
- 협력
- AI
- 구글
- Nextjs
- 카카오
- Rag
- TypeScript
- CSR
- react
- Javascript
- LLM
- It용어
- CSS
- 멀티모달
- HBM
- on-device ai
- 엣지컴퓨팅
- prompt engineering
- SSR
- 스마트안경
- sLLM
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |