JavaScript를 사용하다 보면 값이 없는 상태, 특히 undefined를 어떻게 안전하게 다루어야 할지 고민하게 될 때가 많아. API 응답을 받거나 객체를 탐색할 때 undefined 체크를 제대로 하지 않으면 예상치 못한 에러가 터지기도 하거든. 이 글에서는 JavaScript 개발 흐름에서 자주 사용되는 다양한 undefined 체크 방법을 실제 상황에 맞게 정리했어. undefined가 무엇을 의미하는지부터 시작해서, typeof 비교, 옵셔널 체이닝, 널 병합 연산자까지 차근차근 살펴보자.
undefined는 JavaScript에서 값이 “정의되지 않은 상태”를 나타내는 기본 값이야. 변수를 선언만 하고 값을 할당하지 않았을 때, 존재하지 않는 객체 프로퍼티에 접근했을 때, 함수에 인자를 전달하지 않고 호출했을 때 내부 파라미터, 그리고 return이 없는 함수를 호출한 결과 등 다양한 상황에서 만나게 돼. 이렇게 여러 모습으로 등장하기 때문에, 상황에 맞는 체크 방법을 선택하는 것이 중요해.
목차
undefined 체크 방법 총정리
undefined를 확인하는 방법은 여러 가지가 있어. 각 방법마다 장단점과 적합한 사용 상황이 다르니까, 아래 표를 보면서 내 코드에 가장 잘 맞는 방법을 골라봐.
| 방법 | 사용 예시 | 특징 및 주의사항 |
|---|---|---|
| typeof 비교 | if (typeof value === ‘undefined’) | 가장 안전. 선언되지 않은 변수도 오류 없이 체크 가능. |
| 단순 비교 (=== undefined) | if (value === undefined) | 변수가 이미 선언된 경우에만 사용. 선언되지 않으면 ReferenceError 발생. |
| 느슨한 비교 (== null) | if (value == null) | null과 undefined를 동시에 체크하고 싶을 때 사용. |
| 옵셔널 체이닝 (?. ) | const name = user?.profile?.name | 객체 중첩 탐색 시 undefined가 있어도 안전하게 접근. |
| 널 병합 연산자 (?? ) | const result = value ?? ‘default’ | 값이 null 또는 undefined일 때만 기본값을 할당. |
| OR 연산자 (|| ) | const result = value || ‘default’ | 값이 falsy(0, ”, false 등)일 때도 기본값을 할당하므로 주의 필요. |
| in 연산자 | if (‘name’ in user) | 객체에 프로퍼티 존재 여부를 확인. 값이 undefined여도 true 반환. |
가장 안전한 typeof 비교
undefined 체크에서 가장 기본적이면서도 안전한 방법은 typeof 연산자를 사용하는 거야. if (typeof value === ‘undefined’) 이렇게 쓰면, value라는 변수가 아예 선언되지 않았더라도 ReferenceError가 발생하지 않고 안전하게 체크할 수 있어. 그래서 외부 라이브러리나 브라우저 환경 등 변수의 존재 여부가 불확실할 때 가장 추천하는 방법이지.
객체 탐색의 필수품, 옵셔널 체이닝
API에서 복잡한 JSON 응답을 받거나, 깊이 중첩된 객체의 값을 가져와야 할 때는 옵셔널 체이닝(Optional Chaining)이 정말 유용해. user?.profile?.name 이렇게 물음표를 사용하면, user나 profile이 undefined나 null이어도 코드 실행이 멈추지 않고 그냥 undefined를 반환해. 덕분에 긴 조건문을 한 줄로 간결하게 처리할 수 있어서 코드가 훨씬 깔끔해져.
기본값 지정은 ?? 연산자로
값이 없을 때 기본값을 할당하고 싶다면, 예전에는 OR 연산자(||)를 많이 썼지만 요즘은 널 병합 연산자(??)를 더 선호해. 왜냐하면 || 연산자는 0이나 빈 문자열(”), false 같은 유효한 falsy 값들도 ‘없는 값’으로 판단해서 기본값으로 덮어쓰기 때문이야. 반면에 ?? 연산자는 진짜로 값이 null이나 undefined일 때만 오른쪽의 기본값을 적용해. 그래서 의도치 않은 버그를 피할 수 있어.

undefined 체크가 필요한 실전 상황
API 응답 데이터 처리하기
서버에서 받아온 데이터는 항상 내가 예상한 구조대로 올 거라는 보장이 없어. 그래서 API 응답을 처리할 때는 필수적으로 undefined 체크가 필요해. 예를 들어, res?.data?.items 이런 식으로 옵셔널 체이닝을 사용해 안전하게 접근한 다음, if (typeof items === ‘undefined’) 로 items가 아예 없을 경우에 대한 대응 로직을 작성하는 게 좋아.
함수 파라미터와 옵션 객체 다루기
함수를 만들 때 인자를 선택적으로 받도록 설계하는 경우가 많잖아. 이때 파라미터에 기본값을 설정하거나, 전달된 옵션 객체의 특정 프로퍼티를 안전하게 확인하는 방법을 알아두면 도움이 돼. function setup({ debug } = {}) { const isDebug = debug ?? false; } 이렇게 하면 debug 값이 전달되지 않았을 때도 안전하게 false로 초기화할 수 있어.
undefined와 null의 차이 그리고 타입스크립트
JavaScript를 배우다 보면 undefined와 짝꿍처럼 따라다니는 null도 마주치게 돼. 이 둘은 모두 ‘값이 없음’을 나타내지만, 의미가 조금 다르다는 걸 이해하는 게 중요해. undefined는 시스템이 자동으로 부여하는 ‘아직 값이 할당되지 않음’의 상태라면, null은 개발자가 의도적으로 ‘값이 없음’을 표현하기 위해 할당하는 값이야. 타입스크립트를 사용한다면 이 차이를 더 명확하게 구분하게 돼. 타입스크립트에서는 let name: string | null | undefined; 이런 식으로 union 타입을 써서 어떤 값이 들어올 수 있는지 미리 정의해줄 수 있어. 그리고 strictNullChecks 옵션을 켜두면, 예상치 못한 null이나 undefined가 들어오는 걸 컴파일 단계에서 미리 잡아낼 수 있으니까 꼭 활성화해두는 걸 추천해.
타입스크립트에서의 안전한 처리 팁
타입스크립트에서는 값이 null이나 undefined인지 체크하면, 그 뒤의 코드에서 타입이 자동으로 좁혀지는 ‘타입 좁히기(Type Narrowing)’가 일어나. if (value != null) 이라는 조건은 value가 null도 아니고 undefined도 아닐 때 통과하게 되는데, 이 조건문 안에서는 value가 반드시 유효한 값임을 보장받을 수 있어. 그래서 안전하게 프로퍼티에 접근하거나 메서드를 호출할 수 있게 돼. 또, 옵셔널 체이닝(?.)과 널 병합 연산자(??)는 타입스크립트에서도 동일하게 작동해서 코드를 간결하고 안전하게 만들어 주는 강력한 도구야.
정리하며
지금까지 undefined가 무엇인지, 그리고 그것을 확인하고 안전하게 처리하는 여러 가지 방법에 대해 알아봤어. typeof 비교는 변수의 존재 여부가 불확실할 때 가장 기본이 되는 안전장치이고, 객체를 깊이 탐색할 때는 옵셔널 체이닝이 필수적이야. 값이 없을 때 기본값을 주려면 널 병합 연산자(??)를 사용하는 게 좋고, 타입스크립트를 함께 쓴다면 strict 모드와 union 타입을 활용해서 더욱 견고한 코드를 작성할 수 있어. undefined는 개발 과정에서 자연스럽게 마주치게 되는 존재니까, 두려워하지 말고 상황에 맞는 도구를 잘 선택해서 다루는 연습을 해봐. 조금씩 익숙해지면 에러 메시지에 당황하는 일이 훨씬 줄어들 거야. 앞으로 코드를 작성할 때 이 내용들이 도움이 되길 바라!
더 깊이 알아보고 싶다면, 타입스크립트 핸드북의 공식 문서를 참고하는 것도 좋은 방법이야.
https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#null-and-undefined