값과 타입 비교

notion image
자바스크립트에는 값을 비교하는 세 가지 방법이 있습니다. 값과 타입을 모두 비교하는 === 연산자(일치 연산자), 값의 타입이 다르면 암시적 타입 변환을 하는 == 연산자(동등 연산자), ===연산자와 거의 같은 동작을 하지만 +0, -0, NaN에 예외를 두지 않는 Object.is메서드가 있습니다.

=== 연산자

값과 타입이 모두 일치하는지 비교하기 때문에 두 피연산자가 다른 타입인 경우 false를 반환하지만, +0, -0, NaN이라는 Number 값에 대해서는 예외가 존재합니다.
부동소수점 표준인 IEEE 754에서 0 값의 비교 시 부호는 고려하지 않는다는 정의에 따라 같은 값으로 처리합니다.
NaN은 다른 모든 숫자와의 연산은 모두 NaN이 되고, 비교 연산은 false로 평가됩니다. 만약 NaN이 어떤 값인지 알고 싶다면 Number.isNaN 메서드나 메서드를 사용하면 됩니다. isNaN 전역 함수도 있지만 숫자 타입으로 강제 변환 후 검사하기 때문에 잘못된 결과를 얻을 수 있습니다.
=== 연산자는 배열의 요소를 탐색하는 Array.prototype.indexOf메서드 등에서 내부적으로 사용됩니다. 그래서 배열에 NaN이 존재하는지 확인하기 위해서는 사용할 수 없습니다.

== 연산자

== 연산자는 타입이 다르면 암시적 타입 변환을 진행합니다.
  • 한쪽이 null 또는 undefined라면 다른 쪽 피연산자도 null 또는 undefined인 경우 true 아니라면 false를 반환합니다.
  • 한쪽 피연산자가 객체 타입이고 다른 쪽 피연산자는 원시 타입이라면, 객체 타입을 원시 타입으로 강제 변환 후 비교합니다.
  • 피연산자가 Symbol 타입이라면 false를 반환합니다.
  • 한쪽 피연산자만 Boolean타입이라면 true1로, false0으로 변환 후 비교합니다.
  • 한쪽 피연산자가 String타입이고 다른 쪽 피연산자는 Number타입이라면, String타입을 Number타입으로 변환 후 비교합니다.
  • 한쪽 피연산자가 BigInt타입이고 다른 쪽 피연산자는 Number타입이라면 두 수를 비교합니다. Number타입이 +Infinity, -Infinity 또는 NaN이라면 false를 반환합니다.
  • 한쪽 피연산자가 String 타입이고 다른 쪽 피연산자는 BigInt 타입이라면 String타입을 BigInt로 강제 변환 후 비교합니다.
<, >, <=, >=같은 연산자들 역시 ==와 마찬가지로 타입 강제 변환을 일으킵니다.

Object.is

Object.is 메서드는 ===연산자와 거의 동일하게 동작하지만, +0, -0, NaN 값에 대해 예외를 두지 않습니다.

SomeValueZero 동등 비교

자바스크립트 내부적으로 사용하는 SameValueZero라는 연산자가 존재합니다. NaN이 같다고 판단하는 점 외에는 ===연산자와 동일합니다.
배열에 포함되었는지 반환하는 Array.prototype.includes메서드나 Map, Set 등 자료구조에서 탐색을 위해서 사용됩니다. 그렇기 때문에 Array.prototype.includes 메서드를 사용하면 NaN이 포함되어 있는지 알 수 있습니다.