JavaScript에서 undefined 확인하는 방법 — typeof vs in 연산자
1. 문제 정의
JavaScript에서 변수가 undefined인지 확인할 때 개발자들은 여러 가지 방식을 사용합니다. 대표적으로 다음과 같은 코드가 흔히 등장합니다.
| |
문제는 각 방법이 ‘변수가 무엇을 의미하는지’에 따라 동작이 완전히 다르다는 점입니다. 특히 방법 C는 변수가 선언되지 않았을 때 다음과 같은 에러를 발생시킵니다.
| |
출처: StackOverflow 3390396 - How can I check for “undefined” in JavaScript?
2. 원인 탐구
왜 같은 ‘undefined 확인’ 코드인데 동작이 제각각일까요? 그 이유는 undefined라는 개념이 실제로 두 가지 서로 다른 상황을 포함하기 때문입니다.
| 상황 | 설명 | typeof 결과 |
|---|---|---|
| 선언되지 않은 변수 | var/let/const로 선언된 적이 없음 | "undefined" |
| 선언됐지만 값이 없는 변수 | 선언만 하고 초기화하지 않음 | "undefined" |
선언되지 않은 변수에 직접 접근하면 JavaScript 엔진이 ReferenceError를 던집니다.
| |
따라서 if (myVariable) 같은 직접 접근 방식은 변수가 미선언 상태일 때 프로그램을 즉시 중단시킵니다. 이 에러를 피하려고 Try/Catch를 감싸야 하는지가 질문의 핵심입니다.
또 하나의 함정은 if (window.myVar) 방식입니다. window 속성 접근은 비교가 되지만, falsy 값을 모두 걸러내기 때문입니다.
| |
즉, 변수의 값이 실제로 0이나 빈 문자열이라면 if (window.myVar)로는 undefined와 구분할 수 없습니다.
3. 근본 원인 분석
근본 원인은 확인하고 싶은 것이 ‘존재 여부’인지 ‘값의 종류’인지에 따라 적절한 연산자가 다르다는 데 있습니다.
1) 변수가 선언되었는지(존재 여부)를 알고 싶다면 → in 연산자
in 연산자는 변수가 선언됐는지 여부를 값과 무관하게 확인합니다.
| |
in 연산자는 ‘선언됐지만 초기화되지 않은 변수’도 true로 판별합니다. 값이 아닌 존재 자체를 보기 때문입니다.
2) 변수의 값이 undefined인지 알고 싶다면 → typeof 연산자
typeof는 항상 문자열을 반환하므로, 변수가 선언되지 않아도 ReferenceError 없이 안전하게 확인할 수 있습니다.
| |
3) 왜 undefined와 직접 비교하면 안 되는가?
과거에는 window.undefined를 덮어쓸 수 있었기 때문에 직접 비교가 오염될 수 있었습니다.
| |
다만 @CMS가 지적했듯이, 이는 ECMAScript 5판에서 패치되어 undefined는 더 이상 쓸 수 없게(non-writable) 되었습니다. 그럼에도 typeof 비교는 명시적이고 안전한 관례로 남아 있습니다.
4) 직접 접근이 에러를 일으키는 두 번째 경우
if (myVariable)은 미선언 변수 접근뿐 아니라, getter 함수가 내부에서 예외를 던지는 속성을 접근할 때도 ReferenceError(또는 기타 예외)를 발생시킬 수 있습니다.
4. 코드 해결책
상황에 맞는 안전한 undefined 판별 코드를 정리합니다.
해결책 1: 값이 undefined인지 확인 (가장 일반적)
| |
해결책 2: 변수/속성이 선언(존재)되었는지 확인
| |
해결책 3: NaN 등 다른 falsy 값과 구분
값 자체가 false, 0, "", NaN, null이어도 그 값은 유효한 데이터일 수 있습니다. 값을 보존하면서 판별하려면 진리값 검사 대신 typeof를 쓰는 것이 안전합니다.
| |
방법별 동작 비교 표
| 확인 코드 | 미선언 변수 | 값=undefined | 값=0 / "" / false | 에러 발생 |
|---|---|---|---|---|
if (myVar) | ReferenceError | false | false | ⚠️ 가능 |
if (window.myVar) | false | false | false | 안전 |
if (typeof myVar !== 'undefined') | false | false | true | 안전 |
"myVar" in window | false | true | true | 안전 |
typeof myVar !== 'undefined'와"myVar" in window모두 미선언 변수에 대해false를 반환하지만,in연산자는 값이 undefined인 변수에 대해서도true를 반환한다는 차이가 있습니다.
5. 향후 예방 조치
undefined 확인과 관련된 함정을 피하기 위한 실천 지침입니다.
- 미선언 변수 접근을 피하라 —
if (myVar)처럼 변수를 직접 조건에 넣지 말고, 반드시typeof나in으로 감싸서 접근하세요. 직접 접근은ReferenceError: x is not defined를 일으킵니다. - ‘존재 여부’와 ‘값의 종류’를 구분하라 — 선언됐는지가 궁금하면
in연산자, 값이 undefined인지가 궁금하면typeof연산자를 쓰세요. 둘을 혼용하면 의도와 다른 결과가 나옵니다. - falsy 값 함정을 기억하라 —
if (value)는0,"",false,NaN,null,undefined를 모두 거짓으로 만듭니다. 값 자체를 유효 데이터로 다뤄야 한다면 진리값 검사 대신typeof를 사용하세요. - ES5 이후의 안전성에 의존하라 —
undefined는 SC5에서 non-writable로 고정되었지만, 명시적인typeof비교가 코드 의도를 더 잘 드러냅니다. - 모듈/스코프 단위로 변수를 초기화하라 — 변수를 사용하기 전에 명시적으로 초기화하면 미선언 상태 자체가 발생할 여지를 줄일 수 있습니다.
출처