폼에서 받은 문자열 금액을 숫자와 비교했더니 빈 문자열도 0과 같다고 나옵니다. ==와 ===는 어떻게 다르며 입력을 어떤 순서로 검증하나요?
잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?
답변과 점검 포인트 펼치기답변 접기
구두 답변
정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.
===는 일반적으로 피연산자의 타입을 바꾸지 않고 비교하고, ==는 명세가 정한 규칙에 따라 비교 전에 타입 변환을 시도합니다. 따라서 외부 입력을 비교할 때는 예상 타입을 먼저 정한 뒤 ===를 기본으로 쓰는 편이 안전합니다.
암묵 변환을 경계 밖으로
console.log(0 == false); // true
console.log('' == 0); // true
console.log('5' === 5); // false
console.log(null == undefined); // true
console.log(null === undefined); // false
첫 두 비교에서는 불리언이나 문자열이 숫자처럼 변환되는 규칙이 적용됩니다. null과 undefined는 느슨한 비교에서 서로 같다고 처리되는 특별한 쌍이지만, 다른 일반 값과 폭넓게 같아지는 것은 아닙니다. ===도 모든 의미에서 동일함을 뜻하지는 않습니다. 예를 들어 NaN === NaN은 false이고 0 === -0은 true이므로 숫자의 특수값까지 구별해야 하면 Object.is를 별도로 검토합니다.
파싱과 도메인 값
문자열로 받은 금액을 숫자와 비교해야 한다면 우연히 ==에 맡기지 말고 Number(input)을 명시적으로 변환한 뒤 Number.isFinite 같은 검증을 적용하겠습니다. 다만 Number("")가 0이 되는 등 빈 문자열도 변환될 수 있으므로 금액이라면 변환 전에 허용한 문자열 형식과 빈 값 여부도 확인해야 합니다. 값이 없음을 null 또는 undefined 모두로 표현하기로 한 좁은 계약에서는 value == null을 의도적으로 쓸 수 있지만, 그 사실을 주석과 테스트로 드러내야 합니다. 비교 연산자 하나를 통일하는 것보다 입력 경계에서 타입과 허용 형식을 확정하는 것이 핵심입니다.
선택 기준과 검증
명시적 파싱 뒤에도 Number('')가 0이 되는 규칙, 안전 정수 범위, 금액 단위를 별도로 다뤄야 합니다. 금액을 부동소수점으로 저장하면 표현 오차가 비교 결과를 바꿀 수 있으므로 최소 단위 정수나 decimal 정책을 선택하겠습니다. 비교 연산자 선택과 도메인 값의 정밀도 문제를 같은 해결책으로 포장하지 않겠습니다.
객체와 원시값의 느슨한 비교에서는 객체를 원시값으로 바꾸는 과정이 관여할 수 있습니다. 사용자 정의 Symbol.toPrimitive나 valueOf가 실행되면 비교 한 줄이 단순한 값 검사 이상의 코드를 호출할 수도 있습니다. 외부 입력을 내부 값 객체로 정규화하면 이런 변환 규칙에 우연히 기대지 않고 비교할 수 있습니다. JSON에서 얻은 값도 배열·객체·null의 형태를 먼저 검사해야 합니다.
Object.is는 NaN을 자기 자신과 같게 보지만 +0과 -0을 다르게 봅니다. Map·Set 등에서 사용하는 SameValueZero는 NaN을 같게 취급하면서 두 0도 같게 취급합니다. 따라서 비교 규칙을 바꾸면 컬렉션의 키 의미까지 같은지 확인해야 합니다. 깊은 동등성은 객체 그래프와 순환·날짜·프로토타입을 어떻게 볼지 별도 계약이 필요하므로 ===를 바꾸는 간단한 만능 연산처럼 취급하지 않겠습니다.
득점 포인트
이해가 드러나는 지점을 확인해 보세요.
- 느슨한 비교의 암묵 변환 사례를 설명한다.
- null·undefined·NaN·-0의 예외 규칙을 구분한다.
- 외부 문자열을 명시적으로 파싱·검증하는 순서를 제시한다.
감점 포인트
놓치기 쉬운 조건과 오해를 짚어 보세요.
- ==가 단순 문자열 비교라고 말한다.
- ===만 쓰면 빈 입력·범위·NaN 검증이 끝난다고 설명한다.
- NaN===NaN 또는 0===-0의 특수 규칙을 틀리게 말한다.
더 파고들 거리
하나 더 질문하며 이해의 범위를 넓혀 보세요.
- 객체를 숫자나 문자열과 연산할 때 valueOf·toString·Symbol.toPrimitive는 어떤 순서와 부수 효과를 만들 수 있나요?
- NaN과 -0을 Object.is·===·Set에서 비교합니다. 각 동일성 규칙은 어떤 차이가 있나요?
- 큰 정수 금액을 Number 대신 표현할 때 파싱·직렬화 계약은 무엇인가요?
득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.
원리부터 공부하고 싶다면
답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.