[JavaScript] Object.is 메서드

hyowon·2021년 9월 14일
0

자신과 일치하지 않는 유일한 값

자바스크립트에서 NaN산술 연산 불가(not-a-number)를 뜻한다.
동등 비교 연산자 == 와 일치 비교 연산자 ===NaN을 비교하면 둘다 false 를 반환한다.
NaN 은 자기자신을 비교했을때 일치하지 않는 유일한 값이다.

console.log(NaN == NaN); // false
console.log(NaN === NaN); // false

0*'string' 은 평가결과가 연산불가이므로 NaN이지만 비교한 결과는 false가 나온다.

console.log(0 * 'string' == NaN); // false
console.log(0 * 'string' === NaN); // false

+0-0

자바스크립트에서는 +0-0이 존재한다.
부호가 다르기때문에 일치하지 않는 값이여야 하지만 +0-0 역시 우리가 예측한 값과는 다른 결과가 출력된다.

console.log(+0 == -0); // true
console.log(+0 === -0); // true

그렇다면 어떻게해야 예측한 결과와 동일한 결과를 얻을 수 있을까?

Object.is 메서드

ES6에서 도입된 Object.is 메서드는 다음과 같이 예측 가능한 정확한 비교 결과를 반환한다. 그 외에는 일치 비교 연산자와 동일하게 동작한다.

console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(-0, +0)); // false

Object.is 메서드는 어떻게 비교하는지 궁금해서 mdn을 찾아보니 폴리필 코드를 볼 수 있었다.

폴리필이란?
최신 사양의 기능을 지원하지 않는 브라우저를 위해 누락된 최신 사양의 기능을 구현하여 추가하는 것

Object.is 메서드는 es6부터 도입됐기때문에 es6를 지원하지 않는 IE 브라우저는 Object.is 메서드를 사용하지 못한다.
따라서 IE 브라우저에서 Object.is 메서드를 사용하기 위해서는 폴리필이 필요하다.


if (!Object.is) {
  Object.is = function(x, y) {
    if (x === y) {
      return x !== 0 || 1 / x === 1 / y;
   } else {
     return x !== x && y !== y;
   }
  };
}

코드를 한줄씩 설명해보자면

먼저 Object.is 메서드가 존재하는지 체크한다.
Object 객체에 is 메서드가 존재하지 않는다면 undefined를 반환한다.
undefinedFalsy한 값으로 부정연산자 ! 의 결과는 true가 나온다.

if문 안으로 들어왔다면Object 객체에 is 메서드를 동적생성한다.

기본적으로는 일치비교연산자와 동일하게 동작하기때문에 일치비교연산자를 사용해서 비교한다.

일치비교연산자로+0-0 을 비교하는 경우 true가 나오기때문에 예외 처리를 하기위해서 return x !== 0 || 1 / x === 1 / y; 논리연산자 표현식을 추가한다

연산자 우선순위에 따라서 연산을 하면 다음과 같은 과정을 통해 false 를 반환하게 된다.

//true -> if문 안으로 들어간다
+0 === -0

// false -> 0인지 확인한다. 0이 아닌경우는 단축평가에 의해서 true 반환
+0 !== 0 

//0인경우 나눗셈의 결과를 비교해서 반환
1 / +0  //Infinity 
1 / -0  //-Infinity
Infinity === -Infinity //false

else 문에서는 NaNNaN을 비교했을때를 처리해준다.
NaN은 자기자신과 일치하지않는 유일한 값이기때문에
NaN !== NaNtrue임을 이용해서 NaN 을 판별한다.

NaN === NaN  //false
NaN !== NaN //true
true && true //true

NaN을 확인하는 방법에는 isNaN()이나 Number.isNaN()도 있다.

폴리필 코드를 직접 추가하는 것 보다는
Babel 을 사용하는 것이 좋다.

참고

모던 자바스크립트 Deep Dive
Object.is() - JavaScript | MDN

0개의 댓글