자바스크립트 == 와 === 차이: 동등/일치 연산자 완벽 정리
자바스크립트 == 와 === 차이, 한 문장으로
자바스크립트 == 와 === 차이의 핵심은 타입 변환을 하느냐입니다. ==(느슨한 동등, loose equality)는 비교 전에 양쪽 타입을 자동으로 맞춘 뒤 값을 비교하고, ===(엄격한 일치, strict equality)는 타입 변환 없이 타입과 값이 모두 같아야 true를 반환합니다.
console.log(1 == '1'); // true (문자열 '1'을 숫자로 변환)
console.log(1 === '1'); // false (number vs string, 타입 다름)
console.log(0 == false); // true (false를 0으로 변환)
console.log(0 === false);// false (number vs boolean)== 는 어떻게 타입을 변환할까?
==는 양쪽 타입이 다르면 한쪽을 변환해 다시 비교합니다. 이 규칙 때문에 직관에 어긋나는 결과가 자주 나옵니다.
console.log('' == 0); // true ('' → 0)
console.log('0' == 0); // true ('0' → 0)
console.log('' == '0'); // false (둘 다 문자열, 변환 없음)
console.log(null == undefined); // true (특별 규칙)
console.log(NaN == NaN); // false (NaN은 무엇과도 같지 않음)
console.log([] == false); // true ([] → '' → 0, false → 0)마지막 [] == false가 true인 이유처럼, 느슨한 동등은 규칙이 복잡해 버그의 원인이 됩니다.
=== 는 단순하고 예측 가능
console.log(1 === 1); // true
console.log('a' === 'a'); // true
console.log(null === undefined); // false (타입이 다름)
console.log(NaN === NaN); // false== 와 === 비교 표
| 비교식 | == 결과 | === 결과 |
|---|---|---|
| 1 == '1' | true | false |
| 0 == false | true | false |
| '' == 0 | true | false |
| null == undefined | true | false |
| NaN == NaN | false | false |
실전: 어떤 것을 써야 할까?
대부분의 경우 ===를 기본으로 사용하세요. 예측 가능하고 의도하지 않은 타입 변환 버그를 막아 줍니다. ESLint의 eqeqeq 규칙도 === 사용을 강제합니다.
// 권장: 명확한 비교
if (status === 'active') { /* ... */ }
if (count === 0) { /* ... */ }== 가 유용한 한 가지 예외
null과 undefined를 한 번에 검사할 때는 == null이 간결합니다. 이 둘은 서로 느슨하게 같기 때문입니다.
function hasValue(x) {
// x가 null이거나 undefined면 false
return x != null;
}
console.log(hasValue(0)); // true (0은 값으로 인정)
console.log(hasValue(null)); // false
console.log(hasValue(undefined)); // false이 패턴 외에는 일관성을 위해 ===와 !==를 사용하는 것이 안전합니다.
== 의 변환 규칙을 한 단계 더 이해하기
==가 헷갈리는 이유는 내부 변환 규칙이 단계별로 정해져 있기 때문입니다. 대략 이런 흐름입니다. 타입이 같으면 ===처럼 그대로 비교하고, null과 undefined는 서로만 같다고 봅니다. 숫자와 문자열을 비교하면 문자열을 숫자로 바꾸고, boolean이 끼어 있으면 먼저 숫자(true→1, false→0)로 바꿉니다. 객체(배열 포함)와 원시값을 비교하면 객체를 원시값으로 변환한 뒤 다시 비교합니다.
console.log(true == 1); // true (true → 1)
console.log('123' == 123); // true ('123' → 123)
console.log([1] == 1); // true ([1] → '1' → 1)
console.log(null == 0); // false (null은 0으로 변환 안 됨)
console.log(undefined == 0); // false특히 null == 0이 false인 점에 주의하세요. null은 undefined와만 느슨하게 같고, 숫자로는 변환되지 않습니다. 이런 예외적인 규칙들 때문에 실무에서는 ===를 기본으로 두는 것이 안전합니다.
문자열 입력값을 다룰 때의 실전 팁
웹 폼, input 요소, URL 쿼리 파라미터에서 받은 값은 거의 항상 문자열입니다. 숫자와 비교할 때는 ==의 자동 변환에 기대지 말고 Number()나 parseInt()로 명시적으로 변환한 뒤 ===로 비교하는 습관을 들이면 의도가 분명해지고 버그가 줄어듭니다.
const age = document.querySelector('#age')?.value; // 문자열 '20'
if (Number(age) === 20) {
console.log('스무 살입니다');
}흔한 실수
- 숫자처럼 보이는 문자열 비교: 폼 입력값은 보통 문자열입니다.
userInput === 5는 항상 false일 수 있으니Number(userInput) === 5처럼 명시적으로 변환하세요. - NaN 비교:
x === NaN은 절대 true가 안 됩니다.Number.isNaN(x)를 쓰세요. - 객체 비교 오해:
===는 객체의 "참조"를 비교합니다.{} === {}는 false입니다. 내용 비교가 필요하면 별도 로직이 필요합니다.
자주 묻는 질문
Q1. 그냥 항상 ===만 쓰면 되나요?
대부분 그렇습니다. 예외적으로 null과 undefined를 동시에 검사하는 == null 패턴만 알아두면 충분합니다.
Q2. == 가 더 빠르거나 느린가요?
성능 차이는 사실상 무시할 수준입니다. 선택 기준은 속도가 아니라 "예측 가능성과 버그 방지"입니다.
Q3. 객체나 배열은 어떻게 비교하나요?
==, === 모두 같은 참조인지(같은 메모리 주소인지)만 봅니다. 값(내용)이 같은지 비교하려면 속성을 직접 비교하거나 JSON.stringify 같은 방법을 써야 합니다.