23. 옵셔널 체이닝
2026년 4월 11일
1. 개요 및 등장 배경
왜 필요한가? (The Problem)
데이터를 다루다 보면 존재하지 않는 경로의 프로퍼티를 읽으려 할 때 스크립트가 죽어버리는 현상이 발생합니다.
- 예시:
user.address.street를 읽고 싶은데,user.address가undefined라면? -> 에러 발생! - 과거의 해결책:
&&연산자를 길게 체이닝하여 각 단계를 확인했습니다.user && user.address && user.address.street(코드가 너무 길고 가독성이 낮음)
옵셔널 체이닝의 해결책 (The Solution)
?.을 사용하면 **'?. 앞'**의 대상이 존재하지 않아도 에러를 내지 않고 undefined를 반환하며 조용히 평가를 멈춥니다.
2. 동작 원리: 단락 평가 (Short-circuiting)
?.은 왼쪽 평가 대상이 null 또는 undefined인 경우 즉시 실행을 멈춥니다. 이를 단락 평가라고 합니다.
- 동작 방식:
user?.sayHi(x++)에서user가 없다면, 인자로 전달된x++는 실행조차 되지 않습니다. - 주의사항: 선언되지 않은 변수(ReferenceError)에는 동작하지 않습니다. 반드시 변수 선언(
let,const)이 완료된 상태여야 합니다.
3. 다양한 활용 형태
. 표기법뿐만 아니라 함수 호출과 대괄호 표기법에서도 사용할 수 있습니다.
| 형태 | 설명 | 예시 |
|---|---|---|
obj?.prop | 프로퍼티가 있으면 읽고, 없으면 undefined | user?.address |
obj?.[prop] | 대괄호 표기법(변수 키) 접근 시 사용 | user?.[key] |
obj?.method() | 메서드가 존재할 때만 실행 | user.admin?.() |
- 삭제와의 조합:
delete user?.name;(유저가 있을 때만 이름 삭제) - ⚠️ 주의 - 쓰기 불가:
user?.name = "John"처럼 할당 연산자 왼쪽에서는 사용할 수 없습니다.
4. [Expert Insight] 남용에 대한 경고
옵셔널 체이닝은 편리하지만, **"반드시 있어야 하는 값"**에는 사용하지 않는 것이 원칙입니다.
- 올바른 예: 주소 정보(
address)는 필수값이 아닐 수 있으므로user.address?.street를 사용합니다. - 나쁜 예: 시스템 구조상
user객체는 반드시 존재해야 한다면,user?.address보다는user.address를 써야 합니다.- 만약
user가 없는데?.를 써버리면, 에러가 발생해야 할 곳에서undefined를 조각처럼 남겨 디버깅이 훨씬 어려워집니다. (침묵하는 에러가 가장 무섭습니다.)
- 만약
🎙️ 기술 면접 대비 (Interview Questions)
Q1. 옵셔널 체이닝 ?.과 논리 연산자 &&의 차이점은 무엇인가요? (중급)
답변: 둘 다 에러를 방지하는 용도로 쓰일 수 있지만,
&&는 왼쪽 값이 falsy(0,"",false등)할 때도 멈추는 반면,?.은 오직 nullish(null,undefined)일 때만 멈춥니다. 또한?.은 문법적으로 훨씬 간결하여 중첩된 객체를 탐색할 때 가독성이 압도적으로 좋습니다.
Q2. 옵셔널 체이닝을 할당 연산자 왼쪽(user?.name = "...")에 사용할 수 없는 이유는? (심화)
답변: 옵셔널 체이닝은 값을 읽어오거나 함수를 호출하는 '평가' 단계에서 사용되는 구조체이기 때문입니다. 만약
user가 없다면 왼쪽 식은undefined로 평가되는데, 자바스크립트에서undefined = "..."같은 할당문은 문법적으로 불가능(SyntaxError)하므로 엔진 차원에서 금지되어 있습니다.
Q3. obj?.method()를 호출할 때 obj는 존재하지만 method가 함수가 아닐 경우 어떻게 되나요? (중급)
답변: 옵셔널 체이닝은
method프로퍼티가 존재하는지만 확인합니다. 만약method가 함수가 아닌 다른 타입(예: 숫자)이라면,?.()구문은 이를 함수로 호출하려 시도하다가TypeError를 발생시킵니다. 따라서 확실치 않다면method자체에도?.()를 사용하는 것이 안전합니다.
💡 기억해야 할 중요한 내용
- 에러를 숨기지 마세요. 존재하지 않아도 로직에 지장이 없는 경우에만
?.을 사용해야 프로그램의 건전성을 유지할 수 있습니다. - 연속 체이닝 시 주의:
a?.b?.c?.d처럼 너무 긴 체인은 데이터 구조 설계가 잘못되었다는 신호일 수 있으니 아키텍처를 점검해 보세요.