비교 연산자는 이름처럼 두 개의 값을 비교합니다.
크게 말해 비교 연산자는 일치함(strict equality(===), 동등함(loose equality(==)), 대소 관계의 세 가지 타입으로 나뉩니다(불일치는 일치의 한 종류라고 보기 때문에 다른 타입으로 나누지는 않습니다).
초보자들은 일치와 동등의 차이를 이해하지 못하는 경우가 많습니다.
먼저 일치에 대해 이해해보기로 합시다.
두 값이 같은 객체를 가리키거나, 같은 타입이고 값도 같다면(원시 타입) 이 값을 일치한다고 합니다.
일치 관계는 아주 단순하고 이해하기 쉬우므로 버그나 오해를 낳는 경우가 거의 없습니다.
두 값이 일치하는지 확인할 때는 === 연산자를 쓰거나 그 반대인 !== 연산자를 씁니다.
예제를 살펴보기 전에 먼저 동등 관계를 알아봅시다.
한편, 두 값이 같은 객체를 가리키거나 같은 값을 갖도록 변환할 수 있다면 두 값을 동등하다고 합니다.
역주_ 두 값이 같은 객체를 가리킬 때 일치한다고도 하고 동등하다고도 했는데, 좀 이상하게 읽힐 수도 있지만 저자의 설명이 틀린 것은 아닙니다.
두 값이 일치하면 당연히 두 값은 동등하기도 합니다.
예를 들어 2 === 2는 true이고 2 == 2도 true입니다.
앞 부분은 괜찮지만, 두 번째 부분은 수 많은 골칫거리와 혼란을 발생시켰습니다.
이따금은 편리할 때도 있습니다.
문자열 “33”은 숫자 33으로 변환할 수 있으므로 이 둘은 동등합니다.
하지만 타입이 다르므로 일치하지는 않습니다.
동등 비교가 편리할 때도 있지만, 이런 편리함 때문에 수많은 부작용이 생길 수 있습니다.
따라서 문자열은 미리 숫자로 변환해서 일치하는지 비교하길 권합니다.
동등한지 아닌지 비교할 때는 == 연산자나 != 연산자를 사용합니다.
동등 연산자 때문에 생기는 문제와 함정을 자세히 알고 싶다면 더글러스 크록포드의 자바스크립트 핵심 가이드(한빛미디어, 2008) 를 권합니다.
TIP
동등 연산자 때문에 문제가 생기는 경우는 대개 null과 undefined, 빈 문자열, 숫자 0 때문입니다.
위 네 가지 경우에 해당하지 않는 값을 비교한다면 동등 연산자를 써도 안전할 때가 많습니다.
하지만 기계적으로 동등 연산자를 쓰는 습관은 빨리 버릴수록 좋습니다.
필자가 권하는 대로 일치 연산자만 사용한다면 이런 문제에 대해 생각할 필요도 없습니다.
동등 연산자를 써도 안전한지, 아니면 (미세한) 이득이 있는지 생각하느라 중요한 흐름을 방해받지 않아도 됩니다.
그냥 일치 연산자를 사용하고 계속 진행하면 됩니다.
일치 연산자를 사용했을 때 원하는 결과가 나오지 않으면, 말썽꾸러기인 동등 연산자로 바꾸지 말고 그냥 데이터 타입을 변환하면 됩니다.
프로그래밍은 그 자체로도 충분히 힘든 작업입니다.
동등 연산자를 써서 불필요한 문제를 초래하지 마십시오.
다음은 일치 연산자와 동등 연산자의 예입니다.
객체 a와 b에 같은 정보가 들어 있더라도 그들은 서로 다른 객체이며, 일치하지도 않고 동등하지도 않습니다.
const n = 5;
const s = "5";
n === s; //false -- 타입이 다릅니다.
n !== s; // true
n === Number(s); // true -- 문자열 "5"를 숫자 5로 변환했습니다.
n !== Number(s); // false
n == s; // true; 권장하지 않습니다.
n != s; // false; 권장하지 않습니다.
const a = { name: "an object" };
const b = { name: "an object" };
a === b; // false -- 객체는 항상 다릅니다.
a !== b; // true
a == b; // false; 권장하지 않습니다.
a != b; // true; 권장하지 않습니다.
관계 연산자는 관계가 있는 값을 비교하며, 문자열이나 숫자처럼 원래 순서가 있는 데이터 타입에만 사용할 수 있습니다(‘a’는 항상 ‘b’보다 앞에 있습니다).
관계 연산자에는 작다(<), 작거나 같다(<=), 크다(>), 크거나 같다(>=) 네 가지가 있습니다.
3 > 5; // false
3 >= 5; // false
3 < 5; // true
3 <= 5; // true
5 > 5; // false
5 >= 5; // true
5 < 5; // false
5 <= 5; //true