JavaScript를 개발하거나 디버깅 하는 과정에서 “Cannot read properties of null”, “undefined is not an object” 같은 오류 메시지를 만나면 감정적 스트레스와 생산성 저하를 경험할 수 있음. 이런 오류는 런타임 중에 존재하지 않는 객체나 값에 접근하려 할 때 발생하며, 특히 DOM 조작, API 응답 처리, 객체 체이닝 시 자주 나타남. null 자체는 의도적으로 “값 없음”을 할당한 상태를 의미하고, undefined는 값이 할당되지 않은 상태임을 나타낸다. 하지만 두 값 모두 개발자가 의도하지 않은 시점에 등장하면 예기치 않은 예외를 발생시킴으로써 애플리케이션 전체가 중단될 위험이 있음. 이런 현상은 예를 들어 HTML 요소가 아직 렌더링 되지 않은 상태에서 JavaScript가 해당 요소를 접근하려 할 때, 혹은 서버 응답 객체의 특정 프로퍼티가 null이나 undefined일 때 생김. 따라서 null 관련 오류는 단순한 문법 실수가 아니라 데이터 흐름 및 상태 관리의 문제임을 이해하는 것이 중요함.

심층 분석: null 오류 발생 메커니즘과 JavaScript의 특성
JavaScript는 값이 ‘없음’(absence of value)을 두 가지 방식으로 표현함. 그 중 null은 개발자가 의도적으로 변수에 “값이 없음”을 할당할 때 쓰는 리터럴(keyword)임. 반면 undefined는 변수 선언 후 값이 대입되지 않은 상태로, 엔진이 자동으로 할당하는 기본값임. 예컨대 let x;는 undefined이고, let y = null;은 null 값임. typeof null이 “object”를 반환하는 것은 오래된 버그지만 여전히 사양상 유지되어 있어 디버깅 시 혼란을 야기함. 또한 두 값 모두 Boolean 컨텍스트에서는 false로 평가되지만, ===로 엄격 비교할 때 null은 오직 null과만 같고, undefined와는 같지 않다는 점에 유의해야 함.
null 오류는 특히 객체 내부 깊은 속성을 참조할 때 빈번하게 발생함. 예를 들어 서버 응답으로 받은 JSON 객체가 예상과 다르게 특정 프로퍼티를 포함하지 않을 때 response.data.user.name와 같이 체이닝하면 TypeError가 발생함. 이는 JavaScript가 null이나 undefined 상태에서 프로퍼티를 읽으려 할 때 예외를 던지기 때문임. 따라서 상태가 불분명한 데이터에 대한 방어적 코드가 필수적임.
해결 솔루션 & 데이터 기반 비교
| 기법 / 연산자 | 적용 대상 | 오류 방지 효과 | 부수 영향 |
|---|---|---|---|
| 직접 null 체크 | 단일 값 | 높음 (TypeError 방지) | 코드 장황 가능 |
Optional Chaining ?. |
깊은 객체 프로퍼티 | 높음 (null/undefined 안전 접근) | ES2020+, 브라우저 호환 고려 필요 |
Nullish Coalescing ?? |
값 대체 | 중간 (null/undefined만 대체) | false/0 값 보존 가능 |
| 기본값 초기화 | 변수 선언 | 보통 (논리적 안전) | 의도하지 않은 값 대체 가능 |
- 엄격한 null/undefined 체크: 값을 참조하기 전
if (value === null || value === undefined)를 사용해 조건을 명시적으로 검사함으로써 TypeError를 회피함. 이는 특히 API 응답 데이터에 대해 매우 효과적임. - Optional Chaining 적용: 객체 깊은 속성 접근 시
user?.profile?.name과 같이 작성해 null 또는 undefined 상태에서도 undefined를 반환하도록 함. ES2020 기반의 모던 코드에서 가장 권장되는 방식 중 하나임. - Nullish Coalescing으로 기본값 제공: 값이 null 또는 undefined일 때만 기본값을 제공하는
const result = value ?? defaultValue;패턴을 적용함으로써 다른 falsy 값(예: 0, “”)까지 덮어쓰는 문제를 방지함. - 초기값을 명확히 설정: 변수를 선언할 때 null 또는 적절한 기본값을 할당함으로써 로직에서 불필요한 undefined 상태를 제거함. 예:
let count = 0;등.
전문가 조언 & 팩트체크
- undefined와 null의 구분은 단순 네이밍 이상의 의미를 가지며, undefined는 주로 값이 할당되지 않은 상태를 의미하고 null은 개발자가 “값 없음”을 명시적으로 할 때 사용함.
- ==와 ===의 차이는 중요한 디버깅 포인트임.
==연산자는 null과 undefined를 모두 true로 처리하지만,===는 타입까지 비교함으로써 오탐지를 방지함. - Optional Chaining과 Nullish Coalescing은 ECMAScript 2020 사양으로 모든 모던 브라우저 및 Node.js 환경에서 기본 지원됨. 하지만 레거시 환경에서는 Polyfill이나 트랜스파일러가 필요할 수 있음.
- 과도한 기본값 설정은 코드의 논리적 오류를 감출 수 있으므로, 반드시 의도된 fallback 설계와 함께 사용해야 함. 무조건적인 값 대체는 실제 데이터 문제를 가릴 위험이 있음.
오늘 안내해드린 내용이 여러분들에게 도움이 되었길 바라겠습니다.