JavaScript Truthy와 Falsy 완벽 정리: 헷갈리는 타입 변환, 이제 끝내자!
JavaScript를 처음 접했을 때, truthy와 falsy 개념이 단순하다고 생각했는데, 조금만 깊게 들어가면 상황이 복잡해지는 걸 느꼈습니다.
"false는 falsy, true는 truthy다."라는 기본 개념은 쉽지만, edge case(경계 사례)는 정말 헷갈리는데요.
이번 글에서는 JavaScript의 truthy와 falsy 개념을 깊게 파헤치고, 타입 강제 변환(type coercion)으로 생길 수 있는 문제들을 예제로 정리해 보겠습니다.
Truthy와 Falsy란?
JavaScript에서는 특정 값들이 "참(true)"처럼 평가되거나 "거짓(false)"처럼 평가됩니다.
이를 각각 truthy와 falsy라고 부르는데요. falsy 값은 딱 8가지뿐이고, 나머지는 모두 truthy 값입니다.
JavaScript의 Falsy 값 8가지
다음은 JavaScript에서 falsy로 평가되는 값들입니다:
false // 불리언 false
0 // 숫자 0
-0 // 숫자 음수 0
0n // BigInt 0
"" // 빈 문자열
null // 아무 값도 없음
undefined // 초기화되지 않은 값
NaN // Not a Number
⚠️ 특별한 경우: document.all
document.all
은 JavaScript에서 약간 특이한 존재인데요. 과거 Internet Explorer에서 DOM 요소에 접근하기 위해 사용되던 API입니다. 이 값은 객체(object)이지만, JavaScript는 역사적 이유로 이 값을 falsy로 취급합니다.
헷갈리는 Edge Case들
JavaScript의 타입 강제 변환(type coercion)은 종종 예기치 못한 결과를 만들어냅니다.
대표적인 예제를 살펴볼까요?
1️⃣ 배열의 비교
// 배열
[] == false // true - 빈 배열은 truthy지만, 비교 시 0으로 변환
[1, 2] == true // false - 비어있지 않은 배열은 truthy지만 true와 같지 않음
[] == false
가true
로 평가되는 이유는 JavaScript가 배열을 먼저 원시 값(primitive value)으로 변환하기 때문입니다. 빈 배열([]
)은 빈 문자열(""
)로 변환되고, 이 빈 문자열은 숫자0
으로 변환됩니다. 결과적으로0 == false
는true
가 됩니다.- 반대로,
[1, 2] == true
는false
로 평가됩니다.[1, 2]
는 문자열"1,2"
로 변환되고, 이를 숫자로 변환하려고 하면NaN
이 됩니다.NaN == true
는false
로 평가되죠.
2️⃣ 객체의 비교
// 객체
{} == false // false - 빈 객체는 truthy
new Boolean(false) == false // true - 그러나 객체 자체는 truthy!
{}
(빈 객체)는 truthy한 값입니다. 그러나==
비교에서 빈 객체는[object Object]
라는 문자열로 변환됩니다. 이 문자열은 숫자로 변환할 수 없어서NaN
이 되고,NaN == false
는false
가 됩니다.new Boolean(false)
는 불리언 값false
를 감싸는 객체를 생성하는데요. 이 객체는 truthy한 값이지만,==
비교에서false
와 같게 평가됩니다. 이처럼 감싸진 객체와 원시 값의 비교는 혼란을 줄 수 있으니 주의해야 합니다.
3️⃣ 문자열의 비교
// 문자열
"0" == false // true - 문자열 "0"은 숫자 0으로 변환
"false" == false // false - 문자열 "false"는 숫자로 변환되지 않음
"0" == false
는true
로 평가됩니다."0"
은 숫자0
으로 변환되고,0 == false
는true
가 됩니다."false" == false
는false
로 평가됩니다."false"
는 숫자로 변환되지 못하고NaN
이 되며,NaN == false
는false
가 됩니다.
타입 강제 변환을 막는 방법
위와 같은 혼란을 피하기 위해, 엄격한 동등 연산자(===)를 사용하는 것이 좋습니다.
엄격한 동등 연산자는 타입 강제 변환 없이 값과 타입이 모두 같아야만 true
로 평가됩니다.
실제 사례: 인증 함수 개선하기
타입 강제 변환이 문제를 일으킬 수 있는 실제 사례를 살펴보겠습니다.
문제 있는 코드
function isUserLoggedIn(user) {
return user.loggedIn; // 오류 발생 가능
}
user
가undefined
라면,user.loggedIn
을 접근하려는 시도에서 TypeError가 발생합니다.loggedIn
값이0
,""
,null
등 falsy 값이라면, 의도와 다르게false
로 평가될 가능성이 있습니다.
개선된 코드
function isUserLoggedIn(user) {
if (!user) return false;
return Boolean(user.loggedIn); // 명시적으로 변환
}
- 먼저
user
가 존재하는지 확인해 TypeError를 방지합니다. Boolean()
을 사용해user.loggedIn
의 값을 명시적으로 불리언 값으로 변환합니다.
자주 사용하는 Best Practice 예제
1️⃣ 유효한 역할(role) 반환
function getUserRole(user) {
if (!user?.role) {
return 'guest';
}
return user.role;
}
?.
(옵셔널 체이닝)을 사용해user
나user.role
이null
또는undefined
인 경우를 안전하게 처리합니다.!
를 사용해 falsy 값을 명확히 구분합니다.
2️⃣ 배열 길이 검사
function hasActiveItems(items) {
return Boolean(items?.length);
}
items
가undefined
거나null
인 경우를 처리합니다.- 배열이 비어있으면
false
를 반환합니다.
3️⃣ 숫자 검증
function isValidScore(score) {
return typeof score === 'number' && !Number.isNaN(score);
}
- 숫자인지 확인한 뒤,
NaN
여부를 추가로 체크해 정확성을 높입니다.
4️⃣ 안전한 설정 객체 반환
function getConfig(settings) {
const config = {
theme: settings?.theme ?? 'default',
timeout: settings?.timeout ?? 5000,
retries: settings?.retries ?? 3
};
return config;
}
?.
와??
를 조합해null
또는undefined
일 경우에만 기본값을 설정합니다.||
를 사용하는 경우와 달리,0
이나 빈 문자열 같은 falsy 값도 그대로 유지합니다.
Key Takeaways
JavaScript의 truthy와 falsy 개념은 간단해 보이지만, 타입 강제 변환이 개입되면 예상치 못한 결과를 낳을 수 있습니다. 다음 팁을 기억하세요:
// 항상 엄격한 동등 연산자 사용
value === false // value == false 대신
// 불리언 값으로 명시적 변환
Boolean(someValue) // !!someValue 대신
// 기본값 설정 시 || 대신 ??
const volume = settings?.volume ?? 100;
'Javascript' 카테고리의 다른 글
Node.js에서 AsyncLocalStorage로 비동기 컨텍스트 관리 간소화하기 (0) | 2025.01.08 |
---|---|
자바스크립트 WeakRef 완벽 가이드: 메모리 관리를 쉽게 이해해볼까요? (0) | 2025.01.08 |
자바스크립트 단축 연산자 끝판왕! 논리 AND 할당 연산자 `&&=` 와 Null 병합 할당 연산자 `??=` 로 코드 깔끔하게 정리하기 (0) | 2025.01.08 |
자바스크립트 개발자를 위한 Promise 완벽 가이드: 콜백 지옥 탈출하기 (1) | 2024.12.28 |
React 19 주요 기능 가볍게 살펴보기 (1) | 2024.12.21 |