logo

DowanKim

23. 옵셔널 체이닝

2026년 4월 11일

자바스크립트

1. 개요 및 등장 배경

왜 필요한가? (The Problem)

데이터를 다루다 보면 존재하지 않는 경로의 프로퍼티를 읽으려 할 때 스크립트가 죽어버리는 현상이 발생합니다.

  • 예시: user.address.street를 읽고 싶은데, user.addressundefined라면? -> 에러 발생!
  • 과거의 해결책: && 연산자를 길게 체이닝하여 각 단계를 확인했습니다.
    • 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프로퍼티가 있으면 읽고, 없으면 undefineduser?.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 자체에도 ?.()를 사용하는 것이 안전합니다.


💡 기억해야 할 중요한 내용

  1. 에러를 숨기지 마세요. 존재하지 않아도 로직에 지장이 없는 경우에만 ?.을 사용해야 프로그램의 건전성을 유지할 수 있습니다.
  2. 연속 체이닝 시 주의: a?.b?.c?.d 처럼 너무 긴 체인은 데이터 구조 설계가 잘못되었다는 신호일 수 있으니 아키텍처를 점검해 보세요.