프로그래밍을 하다 보면 ‘값이 없음’을 표현하는 방식이 여러 가지라는 걸 알게 되죠. 특히 자바스크립트와 타입스크립트를 사용할 때 가장 자주 마주치는 것이 바로 undefined와 null입니다. 이 둘은 보기엔 비슷해 보이지만, 사실은 다른 의미를 가지고 있고, 잘못 다루면 예상치 못한 오류를 만날 수 있어요. 오늘은 undefined가 정확히 무엇인지, 그리고 상황에 맞게 어떻게 안전하게 체크하고 처리하는지 하나씩 살펴보려고 합니다. undefined는 단순히 ‘값이 없음’을 넘어서, 아직 정의되지 않은 상태, 존재하지 않는 프로퍼티, 전달되지 않은 인자 등 다양한 모습으로 나타납니다. 반면 null은 개발자가 의도적으로 ‘비어있음’을 표현할 때 사용하는 값이에요. 이 미묘한 차이를 이해하는 것이 안정적인 코드를 작성하는 첫걸음입니다.
| 구분 | 의미 | 주요 체크 및 처리 방법 |
|---|---|---|
| undefined | 값이 할당되지 않았거나 정의되지 않은 상태 | typeof 비교, 옵셔널 체이닝(?.), 널 병합 연산자(??) |
| null | 의도적으로 값이 비어있음을 명시한 상태 | 일치 연산자(===), 널 병합 연산자(??), 타입 가드 |

목차
자바스크립트에서 undefined를 확인하는 방법
자바스크립트에서 undefined는 변수에 값이 할당되지 않았을 때, 함수가 값을 반환하지 않았을 때, 객체에 존재하지 않는 프로퍼티에 접근했을 때 등 여러 상황에서 자연스럽게 등장합니다. 이런 undefined를 제대로 잡아내지 못하면 ‘Cannot read properties of undefined’ 같은 런타임 오류를 마주하게 되죠. 가장 안전하고 널리 사용되는 방법은 typeof 연산자를 이용하는 것입니다. typeof는 변수가 선언되지 않았더라도 참조 오류를 발생시키지 않고 ‘undefined’라는 문자열을 반환하기 때문에, 외부 스크립트나 라이브러리를 사용할 때 특히 유용해요.
만약 변수가 확실히 선언된 상황이라면, 일치 연산자(===)를 사용해 정확히 undefined인지 비교할 수도 있습니다. 이 방법은 코드 의도를 명확히 전달한다는 장점이 있지만, 선언되지 않은 변수에 사용하면 오류가 발생하니 주의가 필요하죠. 때로는 개발 흐름 상 null과 undefined를 구분하지 않고 동일하게 ‘값이 없음’으로 처리하고 싶을 때가 있습니다. 그럴 때는 동등 연산자(==)를 이용해 value == null 조건을 사용할 수 있어요. 이 조건은 값이 null이거나 undefined일 때 참이 되기 때문에, 두 가지 경우를 한 번에 걸러낼 수 있습니다.
옵셔널 체이닝과 널 병합 연산자
최근 자바스크립트에서 undefined와 null을 다루기 정말 편리해졌는데요, 그 주인공이 바로 옵셔널 체이닝(?.)과 널 병합 연산자(??)입니다. 옵셔널 체이닝은 객체의 중첩된 프로퍼티에 안전하게 접근할 때 빛을 발합니다. 예를 들어 사용자 정보를 다루다 보면 user.profile.name 같이 깊은 경로의 값을 가져와야 할 때가 많은데, 중간에 profile이 undefined라면 일반적인 접근 방식은 오류를 일으킵니다. 하지만 user?.profile?.name 이렇게 작성하면, 어떤 단계에서 undefined나 null을 만나더라도 조용히 undefined를 반환하고 실행을 멈춥니다. 이렇게 되면 복잡한 조건문을 작성하지 않아도 되니까 코드가 훨씬 깔끔해지죠.
널 병합 연산자(??)는 값이 null이나 undefined일 때만 지정한 기본값을 사용하게 해줍니다. 예전에는 OR 연산자(||)를 많이 사용했는데, 이 연산자는 0이나 빈 문자열(”), false 같은 유효한 falsy 값들도 기본값으로 덮어쓸 수 있어서 의도치 않은 버그의 원인이 되곤 했어요. 널 병합 연산자는 정말로 값이 없을 때(null이나 undefined일 때)만 대체하므로, 0이나 false 같은 값을 의도적으로 사용하는 경우에는 더 안전한 선택이 됩니다.
타입스크립트에서 null과 undefined 다루기
타입스크립트는 정적 타입 검사를 통해 자바스크립트의 유연함에 안정성을 더해주는 도구입니다. 여기서 null과 undefined는 각각 독립적인 타입으로 취급되기 때문에, 더 명확하게 구분해서 사용할 수 있어요. 기본적으로 타입스크립트의 엄격한 모드(strict mode)에서는 변수에 자동으로 null이나 undefined가 할당되는 것을 막습니다. 따라서 변수가 가질 수 있는 값을 정확히 타입으로 명시해주는 것이 중요한데, 이때 유니온 타입을 자주 사용하게 됩니다. 예를 들어 let username: string | null | undefined; 이렇게 선언하면, username은 문자열일 수도 있고, 명시적으로 null일 수도 있고, 아직 할당되지 않은 undefined일 수도 있다는 걸 컴파일러와 다른 개발자에게 알려줄 수 있죠.
타입 가드와 엄격한 검사
타입스크립트의 장점 중 하나는 조건문을 통해 타입을 좁혀나갈 수 있다는 것입니다. if (value !== null && value !== undefined) 같은 조건을 사용하면, 그 조건 블록 안에서는 value가 null이나 undefined가 아니라는 것을 타입스크립트가 알고, 해당 타입의 메서드를 안전하게 사용할 수 있게 해줍니다. 더 간단히 if (value != null) 이렇게 작성해도 되는데, != 연산자는 null과 undefined를 동시에 체크하기 때문에 편리하게 사용할 수 있어요. 이런 타입 가드를 잘 활용하면 런타임 오류를 컴파일 타임에 미리 발견하는 데 큰 도움이 됩니다.
타입스크립트 프로젝트를 시작할 때 tsconfig.json에서 ‘strictNullChecks’ 옵션을 켜두는 것을 적극 권장합니다. 이 옵션을 키면 모든 타입이 자동으로 null이나 undefined를 포함하지 않게 되어, 의도치 않은 ‘값 없음’이 슬며시 들어오는 것을 방지할 수 있습니다. 만약 null이나 undefined를 허용하고 싶다면, 앞서 말한 것처럼 유니온 타입으로 명시적으로 표시해야 하죠. 처음에는 조금 번거로울 수 있지만, 이 습관이 코드의 신뢰성을 크게 높여준다는 걸 금방 느끼게 될 거예요.
실전에서 바로 적용하는 패턴
이론을 알아봤으니, 이제 실제 코딩에서 어떻게 적용하면 좋을지 몇 가지 상황을 살펴볼게요. 첫 번째는 외부 API에서 데이터를 받아올 때입니다. API 응답 구조는 예상과 다를 수 있으므로, 특히 중첩된 데이터에 접근할 때는 옵셔널 체이닝이 필수적이에요. 응답을 파싱하는 함수를 만들 때, 각 단계마다 undefined 체크를 하면 코드가 너무 길어지고 복잡해질 수 있습니다. 그럴 때는 const userId = response?.data?.user?.id ?? ‘default-id’; 이런 식으로 안전하게 값을 추출하면서 동시에 기본값까지 설정할 수 있습니다.
두 번째는 함수의 매개변수를 처리할 때입니다. 함수를 정의할 때 기본 매개변수 문법을 사용하면 undefined에 대한 걱정을 줄일 수 있어요. function greet(name: string = ‘Guest’) { … } 이렇게 하면 name 매개변수에 아무 값도 전달되지 않거나 undefined가 전달되더라도 ‘Guest’라는 기본값이 할당됩니다. 또한, 객체를 매개변수로 받는 함수에서는 구조 분해 할당과 기본값을 함께 사용하면 더욱 깔끔하게 코드를 작성할 수 있죠.
undefined라는 개념은 프로그래밍을 넘어 우리가 일상에서 마주하는 ‘정의되지 않은 것’, ‘명확히 말할 수 없는 것’을 표현하는 데도 사용되곤 합니다. 예를 들어, 소현우 작가는 ‘유령: Undefined Beings’라는 전시를 통해 실재와 비현실 사이에서 명확히 정의되지 않는 기억과 감각의 흔적을 형상화했습니다. 프로그래밍에서의 undefined가 버그의 원인이 되기도 하지만, 이런 예술적 관점에서는 오히려 새로운 가능성과 해석의 공간을 열어주는 매개체가 되기도 하죠. 전시 정보는 소현우 작가 인스타그램에서 확인할 수 있습니다.
정리하며
지금까지 undefined와 null의 차이점을 중심으로, 자바스크립트에서의 다양한 체크 방법과 타입스크립트에서의 안전한 처리 방식을 알아봤습니다. 가장 중요한 것은 각 상황에 맞는 도구를 선택하는 것이에요. 변수가 선언되었는지 확신이 서지 않을 때는 typeof, 깊은 객체 탐색에는 옵셔널 체이닝, 기본값이 필요할 때는 널 병합 연산자를 먼저 떠올리면 됩니다. 타입스크립트를 사용한다면 엄격한 검사 옵션을 켜고, 유니온 타입을 활용해 의도를 명확히 표현하는 습관을 들이는 게 좋아요. 이러한 작은 습관들이 모여 예측 가능하고 견고한 코드를 만드는 밑거름이 됩니다. 다음번에 코드를 작성하다가 ‘값이 없음’을 표현해야 할 때, 이 글에서 언급한 방법들을 하나씩 적용해 보세요. 분명히 더 자신감 있는 코딩이 가능해질 거예요.





