JavaScript · 2장 기본
형 변환과 비교: == 대신 ===를 쓰는 이유
자바스크립트는 종류가 다른 값을 만나면 한쪽을 몰래 바꿔서 계산하거나 비교해요. 이 자동 변환이 편할 때도 있지만, 버그의 단골 원인이기도 해요. 값을 직접 바꾸는 법과 안전하게 비교하는 법을 정리했어요.
01. 직접 바꾸기: String · Number · Boolean
값의 종류를 바꾸고 싶으면 String(), Number(), Boolean()에 넣어요. 가장 많이 쓰는 건 문자열을 숫자로 바꾸는 Number()인데, 규칙을 알아 두지 않으면 엉뚱한 결과에 놀라요.
console.log(Number('42'), Number(' 42 '), Number('')); // 42 42 0
console.log(Number('12px'), Number('4,200')); // NaN NaN
console.log(Number(true), Number(null), Number(undefined)); // 1 0 NaN
console.log(String(42) + '번', String(null)); // 42번 null
- 앞뒤 공백은 무시하고, 빈 문자열은 0이 돼요. 입력 칸을 비워 둔 것을 "0을 입력함"으로 착각하기 쉬운 지점이에요.
- 숫자로 읽을 수 없는 글자(단위
px, 천 단위 쉼표)가 섞이면NaN이에요.'12px'에서 앞쪽 숫자만 꺼내는parseInt는 숫자 다루기에서 다뤄요. null은 0,undefined는 NaN이 돼요. 둘 다 "없음"이지만 숫자로는 다르게 바뀌어요.
웹 페이지의 입력 칸에서 읽은 값은 숫자를 쳐도 언제나 문자열이에요. 아래 칸에 10, 010, 빈칸, 10원처럼 여러 가지를 넣어 보고, 각 줄의 결과가 어떻게 바뀌는지 보세요.
02. 참 같은 값, 거짓 같은 값
if의 조건 자리에는 아무 값이나 올 수 있고, 그때 값은 불리언으로 바뀌어요. 거짓(false)이 되는 값은 딱 여덟 개예요. false, 0, -0, 0n, 빈 문자열 '', null, undefined, NaN. 나머지는 전부 참이 돼요. 문자열 '0', 공백 ' ', 빈 배열 [], 빈 객체 {}도 참이에요.
console.log(Boolean(0), Boolean(''), Boolean(null), Boolean(NaN)); // false false false false
console.log(Boolean('0'), Boolean(' '), Boolean([]), Boolean({})); // true true true true
const stock = 0;
if (stock) {
console.log('재고 있음');
} else {
console.log('재고 없음 — 0은 거짓이에요');
}
위 예처럼 "값이 있는지"를 if (stock)로 확인하면 0이나 빈 문자열이 정상 값일 때 문제가 생겨요. 재고 0개, 할인율 0%, 빈 메모는 "없음"이 아니라 "0이라는 값"이니까요. 이럴 때 쓰는 ?? 연산자는 다음 글들에서 다뤄요.
03. ==와 ===
같은지 비교하는 연산자가 두 개예요. ===(엄격한 같음)는 종류까지 같아야 true예요. ==(느슨한 같음)는 종류가 다르면 한쪽을 바꾼 뒤에 비교해요. 그 바꾸는 규칙이 복잡해서 결과를 예측하기 어려워요.
console.log(0 == ''); // true
console.log('0' == false); // true
console.log('' == '0'); // false — 앞의 둘과 이어지지 않아요
console.log(null == undefined, null == 0); // true false
console.log(NaN == NaN, NaN === NaN); // false false
그래서 비교는 언제나 ===와 !==를 기본으로 써요. 종류가 다르면 먼저 직접 바꾼 다음 비교해요. 예외로 많이 쓰는 한 가지가 value == null이에요. ==는 null과 undefined를 서로만 같다고 보기 때문에, 이 한 줄로 "값이 없음"을 둘 다 잡아낼 수 있어요.
NaN은 어떤 값과도, 심지어 자기 자신과도 같지 않아요. 계산 결과가 NaN인지 확인할 때는 Number.isNaN(value)를 써요.
04. 문자열끼리 크기를 비교하면
< >로 문자열 두 개를 비교하면 숫자 크기가 아니라 사전 순서로 비교해요. 첫 글자부터 하나씩 비교하다가 처음 다른 글자에서 결정해요. 그래서 '10'이 '9'보다 작다고 나와요.
console.log('10' < '9'); // true — '1'이 '9'보다 앞이에요
console.log(Number('10') < Number('9')); // false
console.log('apple' < 'banana', 'Zoo' < 'apple'); // true true — 대문자가 소문자보다 앞
console.log('10' < 9); // false — 한쪽이 숫자면 숫자로 비교해요
입력 칸 두 개의 값을 비교하거나, 문자열로 저장된 가격을 비교할 때 이 버그가 자주 생겨요. 이것도 비교 전에 숫자로 바꾸면 사라져요.
아래 여섯 줄의 결과를 먼저 예상해 보고 실행해 보세요. 그다음 ==를 모두 ===로 바꿨을 때 결과가 바뀌는 줄을 찾아보세요.
console.log(1 == '1');
console.log(false == 0);
console.log(null == false);
console.log(undefined == null);
console.log('5' > '40');
console.log(Boolean('false'));
해답 보기
차례로 true, true, false, true, true, true예요.
null == false가false인 건,==가null을undefined말고는 무엇과도 같다고 보지 않기 때문이에요.'5' > '40'은 사전 순서 비교라서'5'가'4'보다 뒤예요.- 문자열
'false'는 빈 문자열이 아니라서 참이에요. ===로 바꾸면 첫째 · 둘째 · 넷째 줄이false로 바뀌어요.
05. 실전 포인트
- 언제 쓰나요? 밖에서 들어온 값(입력 칸 · 주소 · 서버 응답)은 들어오는 자리에서 한 번 원하는 종류로 바꿔 두고, 그 뒤로는 바뀐 값만 써요. 비교는
===·!==로 해요. - 대신 쓰는 것:
==는value == null한 가지 용도로만 써요. ESLint의eqeqeq규칙(3장)을 켜면 나머지==를 찾아 줘요. NaN 확인은Number.isNaN이에요. - 흔한 실수: 빈 입력이
Number('')로 0이 되어 "0을 입력함"으로 처리되는 것,if (count)가 0을 "없음"으로 취급하는 것, 문자열 숫자를<로 비교하는 것이에요.
정리
Number()는 공백을 무시하고, 빈 문자열을 0으로, 읽을 수 없는 글자를 NaN으로 바꿔요.- 거짓이 되는 값은
false·0·-0·0n·''·null·undefined·NaN여덟 개뿐이에요. - 비교는
===가 기본이에요.==는value == null에만 써요. - 문자열끼리의
<·>는 사전 순서예요. 숫자로 바꾼 뒤 비교해요.