자바스크립트에서 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
그렇다면 어떻게해야 예측한 결과와 동일한 결과를 얻을 수 있을까?
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
를 반환한다.
undefined
는 Falsy
한 값으로 부정연산자 !
의 결과는 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 문에서는 NaN
과 NaN
을 비교했을때를 처리해준다.
NaN은 자기자신과 일치하지않는 유일한 값이기때문에
NaN !== NaN
은 true
임을 이용해서 NaN
을 판별한다.
NaN === NaN //false
NaN !== NaN //true
true && true //true
NaN
을 확인하는 방법에는 isNaN()
이나 Number.isNaN()
도 있다.
폴리필 코드를 직접 추가하는 것 보다는
Babel
을 사용하는 것이 좋다.
모던 자바스크립트 Deep Dive
Object.is() - JavaScript | MDN