FE/JS
null, undefined, undeclared, NaN
고감귤
2025. 5. 17. 11:14
null, undefined, undeclared, NaN을 헷갈리면 어떤 일이 생길까?
- 없는 값을 체크한다고 생각했는데, 그 값이 NaN이라 의도치 않게 연산이 꼬인다.
- undefined라고 생각한 값을 null만 체크해서 조건문이 통과되지 않는다.
- 선언된 줄 알았던 변수가 실제로는 undeclared 상태라 런타임 에러가 난다.
그래서 이 네 가지 개념을 한 번에 정리해보자.
1. null – 의도적으로 비어있음을 표현
- 정의: 명시적으로 "값이 없음"을 나타내기 위해 사용하는 값
- 타입: object (설계 오류로 인해 typeof null은 "object" 반환)
- 예시:
- 특징:
- 의도적으로 비어 있음을 명시
- 주로 객체 초기화에 사용
- null == undefined → true (느슨한 비교: 형 변환 발생)
- null === undefined → false (엄격한 비교: 타입 다름)
- typeof null === 'object'는 자바스크립트 설계상의 버그
2. undefined – 값이 할당되지 않음
- 정의: 변수가 선언되었지만 초기화되지 않은 상태에서 자동으로 할당되는 값
- 타입: undefined
- 예시:
let x;
console.log(x); // undefined
function doNothing() {}
console.log(doNothing()); // undefined
const obj = {};
console.log(obj.name); // undefined
- 특징:
- 변수는 선언되었지만 값이 없는 상태
- 함수에서 반환값이 없으면 undefined 반환
- 존재하지 않는 객체 속성 접근 시 undefined 반환
- 배열의 빈 슬롯도 undefined 반환
- typeof 검사 시 "undefined" 반환
3. undeclared – 선언되지 않은 변수
- 정의: 스코프 내에 변수 선언 자체가 없는 상태에서 접근 시도한 경우
- 타입: 없음 (ReferenceError 발생)
- 예시:
console.log(notDeclared);
// ReferenceError 발생
// typeof로 안전하게 검사 가능
if (typeof notDeclared === 'undefined') {
console.log('notDeclared는 선언되지 않았습니다.');
} else {
console.log(notDeclared);
}
- 특징:
- typeof undeclaredVar는 "undefined"를 반환하므로 안전하게 검사 가능
- use strict 모드에서는 선언 없는 할당도 에러 발생
'use strict';
undeclaredVar = 5; // ReferenceError
4. NaN – Not a Number (숫자가 아님)
- 정의: 숫자가 아닌 값을 숫자처럼 연산하려 할 때 나오는 결과
- 타입: number
- 예시:
let result = 'hello' / 2;
console.log(result); // NaN
Number('abc'); // NaN
console.log(NaN === NaN); // false
console.log(Number.isNaN(NaN)); // true
console.log(Object.is(NaN, NaN)); // true
- 특징:
- NaN === NaN은 false → 자기 자신과도 같지 않은 유일한 값
- 비교 시 Number.isNaN() 또는 Object.is() 사용 필요
- 타입은 number → 숫자로 오해하기 쉬움
📌 요약 비교표
개념 | 정의 | 타입 | 발생 조건 | 기타 특징 |
null | 의도적으로 비어있음을 명시 | object | 명시적 초기화 | 느슨한 비교 시 undefined와 같음 |
undefined | 값이 할당되지 않음 | undefined | 선언만 했지만 값 미할당 | 객체 속성 없음, 함수 반환 없음 등 |
undeclared | 변수 선언 자체가 없음 | 없음 | 스코프 내 선언 없는 변수 접근 시 | typeof 검사 가능, ReferenceError 발생 |
NaN | 숫자가 아님 | number | 잘못된 수학 연산 또는 숫자 변환 실패 | 자기 자신과도 같지 않음, 비교 시 특별 처리 필요 |
추가 정리: let / const와 TDZ (Temporal Dead Zone)
- let, const는 호이스팅되지만 초기화되기 전까지는 접근할 수 없는 TDZ 상태에 있음
- 이 상태에선 typeof로 검사하거나 if 조건문으로도 우회 불가능
if (typeof tdzVar === 'undefined') {
console.log('검사한 것 같지만...');
}
let tdzVar = 1; // ❌ ReferenceError 발생
- 변수는 스코프 안에 존재하지만 초기화되기 전까지는 접근 불가 → ReferenceError
- undeclared와는 다르게 실제 선언은 되어 있음 (즉, 존재는 하지만 사용할 수 없음)