?. 와 ?? — 자바스크립트 생존 문법
이 토픽을 마치면
?.와 ??가 왜 나왔는지 이해하고, undefined 때문에 터지는 에러를 우아하게 막을 수 있습니다.
API 응답이 왔는데 터진다
서버에서 사용자 정보를 받아옵니다:
const user = await fetch('/api/user').then(r => r.json());
console.log(user.address.city);잘 됩니다. 그런데 어떤 사용자는 주소를 등록하지 않았습니다. user.address가 undefined입니다.
TypeError: Cannot read properties of undefined (reading 'city')이 에러를 한 번도 안 본 JS 개발자는 없습니다. undefined인 걸 모르고 그 안의 속성에 접근하면 터집니다.
옛날 방식 — if 지옥
let city;
if (user && user.address && user.address.city) {
city = user.address.city;
} else {
city = '미등록';
}동작은 합니다. 근데 depth가 깊어지면 이렇게 됩니다:
if (user && user.company && user.company.department && user.company.department.manager && user.company.department.manager.name) {
// ...
}읽을 수가 없습니다.
Optional Chaining — ?.
const city = user?.address?.city;끝입니다. ?.는 **"왼쪽이 null이나 undefined면 거기서 멈추고 undefined를 반환"**합니다. 에러를 내지 않습니다.
user?.address?.city
// user가 null/undefined → undefined 반환 (에러 X)
// user.address가 null/undefined → undefined 반환 (에러 X)
// 둘 다 있으면 → city 값 반환메서드 호출에도 쓸 수 있습니다:
user?.getProfile?.();
// getProfile이 없으면 에러 대신 undefined배열 인덱스에도:
const first = users?.[0]?.name;Nullish Coalescing — ??
?.가 undefined를 반환하면 기본값을 주고 싶을 때 ??를 씁니다:
const city = user?.address?.city ?? '미등록';"city가 null이나 undefined면 '미등록'을 쓴다." 이게 전부입니다.
"그럼 ||랑 뭐가 다르지?" — 아주 중요한 차이가 있습니다:
const count = 0;
console.log(count || 10); // 10 — 0은 falsy니까!
console.log(count ?? 10); // 0 — 0은 null/undefined가 아니니까| 값 | || (OR) | ?? (Nullish) |
|---|---|---|
null | 기본값 사용 | 기본값 사용 |
undefined | 기본값 사용 | 기본값 사용 |
0 | 기본값 사용 | 원래 값 유지 |
'' (빈 문자열) | 기본값 사용 | 원래 값 유지 |
false | 기본값 사용 | 원래 값 유지 |
||는 falsy 전부(0, '', false, null, undefined)를 걸러내고, ??는 null과 undefined만 걸러냅니다. 0이나 빈 문자열이 유효한 값일 때는 ??를 써야 합니다.
실전 조합
// API 응답 안전하게 파싱
const userName = response?.data?.user?.name ?? '익명';
const age = response?.data?.user?.age ?? 0;
const tags = response?.data?.user?.tags ?? [];
// DOM 안전하게 접근
document.querySelector('.header')?.classList.add('active');
// 콜백 안전하게 호출
config.onSuccess?.(result);주의할 점
?.를 남용하지 마세요. 모든 곳에 ?.를 붙이면 어디서 null이 된 건지 추적할 수 없습니다:
// 나쁜 습관 — 에러를 삼켜버림
const value = a?.b?.c?.d?.e?.f ?? 'default';
// 여기서 default가 나왔는데, 어디서부터 null이었지??.는 **"여기가 없을 수 있다"**고 확신하는 곳에만 쓰세요. API 응답, 선택적 설정, DOM 쿼리처럼 실제로 없을 수 있는 곳이 적절합니다.
핵심
?.는 null/undefined면 에러 대신 undefined를 반환합니다. "안전하게 접근."??는 null/undefined일 때만 기본값을 적용합니다.||와 달리 0과 ''를 살려둡니다. 둘의 조합:user?.address?.city ?? '미등록'— 이게 모던 JS의 기본 패턴입니다.