핵심 요약
==(느슨한 비교)는 양쪽 타입이 다르면 강제로 변환한 뒤 비교해 예측이 어렵다. ===(엄격한 비교)는 타입이 다르면 즉시 false다. 규칙은 간단하다 — 기본은 항상 ===, 예외적으로 null/undefined를 한 번에 검사할 때만 == null을 의도적으로 쓴다.
1. == 가 배신하는 예
0 == "" // true 😱
0 == "0" // true
"" == "0" // false (위 둘 다 true인데!)
null == undefined // true
[] == ![] // true 😱
1 == true // true
강제변환 규칙이 얽혀 "같은 것 같지만 다른" 모순이 나온다.
2. === 는 명확하다
0 === "" // false
0 === "0" // false
1 === true // false
"5" === 5 // false
타입이 다르면 무조건 false. 예측 가능하다.
3. 딱 하나 유용한 == 패턴
// null과 undefined를 한 번에 검사
if (value == null) { ... }
// === 로 하면 두 번 써야 함
if (value === null || value === undefined) { ... }
4. 강제변환 기본 규칙(참고)
| 비교 | 동작 |
|---|---|
| 숫자 vs 문자열 | 문자열을 숫자로 변환 |
| 불린이 껴 있으면 | 불린을 숫자(0/1)로 |
| 객체 vs 원시값 | 객체를 원시값으로(valueOf/toString) |
| null == undefined | 서로만 true, 다른 건 false |
5. 실무 지침
- ESLint
eqeqeq규칙을 켜서==사용을 막는다(null 예외 허용 옵션 있음) NaN은===로도 자기 자신과 false —Number.isNaN()으로 검사- 값 존재 확인은
== null보다 명시적?.·기본값(??)이 더 읽기 쉬울 때가 많다
자주 묻는 질문
== 는 절대 쓰면 안 되나요?
기본은 === 입니다. 다만 x == null은 null과 undefined를 동시에 걸러주는 관용구로 널리 쓰입니다. 이 목적이 분명할 때만 의도적으로 쓰고, 나머지는 전부 === 로 통일하세요.
[] == ![] 가 왜 true인가요?
![]는 false가 되고, 이어 양쪽이 숫자로 강제변환됩니다. 빈 배열은 0, false도 0이 되어 0 == 0이 되죠. 이런 예측 불가한 결과 때문에 == 를 피하는 겁니다.
NaN 비교는 왜 특별한가요?
IEEE 754 규정상 NaN은 자기 자신과도 같지 않습니다(NaN === NaN이 false). 그래서 값이 NaN인지 확인할 땐 비교 대신 Number.isNaN(x)를 써야 합니다.

댓글 0