서론
JavaScript로 개발하다 보면 조건문에서 ==랑 ===를 뭘 쓸지 고민하게 됨
처음엔 "둘 다 같은 거 비교하는 거 아닌가?" 싶었는데, 실제로 써보니 ==가 예상과 다르게 동작하는 경우가 꽤 있었음
예를 들어 API에서 받은 데이터가 문자열 "1"인데 숫자 1과 비교할 때, ==로 비교하면 true가 나오길래 편하다고 생각했음
근데 나중에 null == undefined이 true라든가, "" == 0이 true라는 걸 보고 "이건 좀 위험하다" 싶었음
면접에서도 ==와 ===의 차이는 거의 무조건 나오는 질문이고, 타입 변환(Type Coercion)까지 설명할 수 있어야 제대로 된 답변이 되겠다 싶어서 정리해봄
본론
1. == (동등 연산자, Loose Equality)
==는 비교할 때 타입이 다르면 타입을 변환한 후 비교함
console.log(1 == '1'); // true — 문자열 '1'을 숫자 1로 변환 후 비교
console.log(true == 1); // true — true를 숫자 1로 변환 후 비교
console.log(null == undefined); // true — 특별 규칙
console.log('' == 0); // true — 빈 문자열을 숫자 0으로 변환 후 비교
이렇게 자동으로 타입을 맞춰주는 걸 타입 변환(Type Coercion)이라고 함
편해 보이지만, 예상치 못한 true가 나오는 경우가 많아서 버그의 원인이 됨
2. === (일치 연산자, Strict Equality)
===는 타입 변환 없이 타입과 값 모두 같아야 true를 반환함
console.log(1 === '1'); // false — 숫자 vs 문자열, 타입이 다름
console.log(true === 1); // false — 불리언 vs 숫자, 타입이 다름
console.log(null === undefined); // false — null vs undefined, 타입이 다름
console.log('' === 0); // false — 문자열 vs 숫자, 타입이 다름
타입까지 체크하니까 의도하지 않은 비교를 방지할 수 있음
그래서 실무에서는 거의 항상 ===를 사용함
3. 타입 변환(Type Coercion) 규칙 정리
==가 내부적으로 어떻게 타입을 변환하는지 알아야 면접에서 제대로 설명할 수 있음
3-1. 숫자와 문자열 비교 → 문자열을 숫자로 변환
console.log(1 == '1'); // true — Number('1') → 1
console.log(0 == ''); // true — Number('') → 0
console.log(0 == '0'); // true — Number('0') → 0
console.log('' == '0'); // false — 둘 다 문자열이라 변환 없이 비교
3-2. 불리언이 포함된 비교 → 불리언을 숫자로 변환
console.log(true == 1); // true — Number(true) → 1
console.log(false == 0); // true — Number(false) → 0
console.log(true == '1'); // true — true → 1, '1' → 1
console.log(false == ''); // true — false → 0, '' → 0
3-3. null과 undefined
console.log(null == undefined); // true — 특별 규칙 (서로만 같음)
console.log(null == 0); // false — null은 0으로 변환 안 됨
console.log(null == ''); // false
console.log(null == false); // false
console.log(undefined == 0); // false
console.log(undefined == ''); // false
console.log(undefined == false); // false
null과 undefined는 ==로 비교하면 서로에게만 true이고, 나머지는 전부 false임
이건 외워야 함
3-4. 객체와 원시 타입 비교 → 객체를 원시 타입으로 변환
console.log([1] == 1); // true — [1].valueOf() → [1], [1].toString() → '1' → 1
console.log([''] == ''); // true — [''].toString() → ''
console.log([null] == ''); // true — [null].toString() → ''
객체는 valueOf() → toString() 순서로 원시 값으로 변환됨
4. 타입 변환의 종류
JavaScript에서 타입 변환은 두 가지로 나뉨
4-1. 암묵적 타입 변환 (Implicit Coercion)
자바스크립트 엔진이 자동으로 타입을 변환하는 것
// 문자열 변환
console.log(1 + '2'); // '12' — 숫자가 문자열로 변환
console.log('5' - 1); // 4 — 문자열이 숫자로 변환 (- 연산자는 숫자만 가능)
// 불리언 변환
if ('hello') {
console.log('truthy!'); // 출력됨 — 비어있지 않은 문자열은 truthy
}
if (0) {
console.log('출력 안 됨'); // 0은 falsy
}
+ 연산자는 문자열이 하나라도 있으면 문자열 결합으로 동작함-, *, / 연산자는 숫자로 변환을 시도함
이 차이 때문에 실수가 생기기 쉬움
4-2. 명시적 타입 변환 (Explicit Coercion)
개발자가 직접 타입을 변환하는 것
// 문자열로 변환
String(123); // '123'
(123).toString(); // '123'
// 숫자로 변환
Number('123'); // 123
parseInt('123px'); // 123 — 숫자 부분만 파싱
parseFloat('3.14'); // 3.14
+'123'; // 123 — 단항 + 연산자
// 불리언으로 변환
Boolean(1); // true
Boolean(''); // false
!!0; // false — !! 패턴 (실무에서 자주 씀)
!!'hello'; // true
실무에서는 암묵적 변환에 의존하지 않고 명시적으로 변환하는 게 안전함
5. Falsy와 Truthy 값 정리
타입 변환을 이해하려면 falsy/truthy를 알아야 함
Falsy 값 (false로 평가되는 값, 외울 것!)
Boolean(false); // false
Boolean(0); // false
Boolean(-0); // false
Boolean(0n); // false (BigInt)
Boolean(''); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
이 8가지만 falsy이고, 나머지는 전부 truthy
주의: 헷갈리는 truthy 값들
Boolean([]); // true — 빈 배열도 truthy!
Boolean({}); // true — 빈 객체도 truthy!
Boolean('0'); // true — 문자열 '0'도 truthy!
Boolean('false'); // true — 문자열 'false'도 truthy!
빈 배열 []과 빈 객체 {}가 truthy라는 건 자주 실수하는 부분임
6. 실무에서 겪을 수 있는 문제
Before: == 때문에 생기는 버그
// API에서 받은 응답값 체크
const response = { status: 0 };
// ❌ == 사용 시
if (response.status == false) {
console.log('실패!'); // 출력됨 — 0 == false → true
}
// 의도: status가 false인지 확인
// 실제: status가 0인데 false로 판단해버림
// ❌ 또 다른 케이스
const input = '';
if (input == false) {
console.log('입력값 없음'); // 출력됨 — '' == false → true
}
// 빈 문자열과 false를 같다고 판단
After: === 사용으로 명확한 비교
// ✅ === 사용
const response = { status: 0 };
if (response.status === false) {
console.log('실패!'); // 출력 안 됨 — 0 !== false (타입이 다름)
}
if (response.status === 0) {
console.log('status가 0임'); // 이렇게 명확하게 비교해야 함
}
// ✅ 입력값 체크도 명확하게
const input = '';
if (input === '' || input === null || input === undefined) {
console.log('입력값 없음');
}
// 또는 더 간결하게
if (!input) {
console.log('입력값 없음'); // falsy 체크
}
7. == 를 써도 괜찮은 경우
===를 기본으로 쓰되, ==가 유용한 케이스가 딱 하나 있음
// null 또는 undefined인지 한 번에 체크할 때
if (value == null) {
// value가 null이거나 undefined일 때만 여기 들어옴
// 0, '', false는 여기 안 들어옴
}
// === 로 하면 두 번 써야 함
if (value === null || value === undefined) {
// 같은 동작이지만 더 길음
}
value == null은 null과 undefined만 true로 판단하기 때문에, 이 패턴은 실무에서도 종종 사용됨
다만 ESLint 규칙에 따라 팀마다 허용 여부가 다를 수 있음
8. 면접 예상 질문 & 답변
Q1. == 와 === 의 차이는 무엇인가요?
==(동등 연산자)는 비교 시 타입이 다르면 타입 변환을 수행한 후 비교합니다.===(일치 연산자)는 타입 변환 없이 타입과 값 모두 동일해야true를 반환합니다. 예를 들어1 == '1'은true이지만,1 === '1'은false입니다.
Q2. 타입 변환(Type Coercion)이란 무엇인가요?
타입 변환은 JavaScript 엔진이 연산 시 피연산자의 타입을 자동으로 변환하는 것을 말합니다. 암묵적 변환(Implicit)은 엔진이 자동으로 수행하고, 명시적 변환(Explicit)은
Number(),String(),Boolean()등을 사용해 개발자가 직접 수행합니다.
Q3. falsy 값을 모두 말해보세요.
false,0,-0,0n(BigInt),''(빈 문자열),null,undefined,NaN총 8가지입니다. 이 외의 값은 모두 truthy이며, 빈 배열[]과 빈 객체{}도 truthy입니다.
Q4. null == undefined가 true인 이유는?
ECMAScript 명세에서
==연산 시null과undefined는 서로에게만 동등하다고 정의되어 있습니다. 이 둘은 "값이 없음"을 나타내는 공통점이 있어서 동등 연산에서 같다고 처리됩니다. 다만===로 비교하면 타입이 다르므로(null은 object,undefined는 undefined)false가 됩니다.
Q5. 실무에서 ==와 ===중 어떤 걸 사용해야 하나요?
기본적으로 항상
===를 사용하는 것이 좋습니다. 타입 변환으로 인한 예상치 못한 버그를 방지할 수 있기 때문입니다. 유일하게== null패턴은null과undefined를 한 번에 체크할 수 있어서 실무에서 허용되는 경우가 있습니다.
결론
==과 ===는 단순해 보이지만, 타입 변환까지 이해해야 제대로 쓸 수 있음
==: 타입이 다르면 변환 후 비교 (느슨한 비교)===: 타입 변환 없이 타입 + 값 모두 비교 (엄격한 비교)- 타입 변환: 숫자 ↔ 문자열, 불리언 → 숫자, 객체 → 원시 타입 순서로 변환됨
- falsy 값:
false,0,-0,0n,'',null,undefined,NaN - 실무 원칙: 항상
===사용,== null패턴만 예외적으로 허용
| 구분 | == (동등) |
=== (일치) |
|---|---|---|
| 타입 변환 | 수행함 | 수행 안 함 |
1 == '1' / 1 === '1' |
true |
false |
null == undefined / null === undefined |
true |
false |
'' == false / '' === false |
true |
false |
| 사용 권장 | == null 패턴만 |
기본으로 사용 |
프로젝트에서 ESLint의 eqeqeq 규칙을 켜두면 ==를 쓸 때 경고가 나와서 실수를 방지할 수 있음
앞으로도 ===를 기본으로 쓰고, 타입이 애매할 땐 명시적으로 변환해서 비교하는 습관을 들여야겠음!
'프론트엔드 > JavaScript' 카테고리의 다른 글
| (JavaScript) var vs let vs const 차이 (TDZ 포함) (0) | 2026.02.09 |
|---|---|
| (JavaScript) 프로토타입과 프로토타입 체인 (0) | 2026.02.06 |
| (JavaScript) 스코프(Scope)와 스코프 체인 (0) | 2026.02.03 |
| (JavaScript) 호이스팅(Hoisting) 완벽 정리 (var, let, const, 함수) (0) | 2026.02.02 |
| (JavaScript) 클로저(Closure)란 무엇인가? (0) | 2026.02.01 |