(NaN! = NaN)과 (NaN! == NaN)의 차이점은 무엇입니까?


148

우선 나는 방법 isNaN()Number.isNaN()작업을 알고 있다고 언급하고 싶습니다 . David Flanagan 의 Definite Guide 를 읽고 있으며 값이 NaN다음 과 같은지 확인하는 방법에 대한 예를 제공합니다 .

x !== x

true경우 if 만 x입니다 NaN.

그러나 이제 질문이 있습니다. 왜 엄격한 비교를 사용합니까? 그것은 보인다

x != x

같은 방식으로 작동합니다. 이 두 버전을 사용하거나 내가 돌아 자바 스크립트에서 어떤 값 (들) 실종 안전 true을 위해 x !== xfalse위해를 x != x?


10
Flanagan은 !==수표보다 !=수표를 선호 할 수 있습니다 . 내가 아는 한 where where 다른 값은 없습니다 x != x. 그러나 JavaScript 개발자에는 두 가지 뚜렷한 그룹이 있습니다. 선호하는 사람 !=과 선호 하는 사람은 !==속도, 선명도, 표현력 등이 있습니다.
Steve Klösters

30
엄격한 비교가 같은 방식으로 동작 할 때 느슨한 비교를 사용하는 이유는 무엇입니까?
Ry-

3
@Raulucco : NaN고유 한 유형이 아니며 숫자입니다. 자체와 같지 않은 고유 한 입니다.
TJ Crowder

8
제목이 사람들을 오도하는 것 같습니다. "x! = x와 x! == x가 다른가?"와 같은 것으로 변경하는 것이 좋습니다.
TJ Crowder

6
@femmestem : Giorgi는 "이 경우"는 스타일의 문제라고 말했습니다. 그리고 그는 맞습니다. 그것은 아닌 피연산자의 유형이 다른 경우 스타일, 그러나 그것은 이다 가 동일한있을 때 스타일. 별도로 : Flanagan은 ===NaN과의 비교 를 통해 NaN이 자신과 같지 않다는 지적 합니다. 그는 "잘못되지 않았습니다"라고 가르치는 연습으로하고 있는데, 그것이 효과가 없다는 것을 보여줍니다.
TJ Crowder

답변:


128

먼저 NaN매우 특별한 가치를 지적하겠습니다 . 정의에 따르면, 그것은 그 자체와 같지 않습니다. 이는 JavaScript 숫자가 사용하는 IEEE-754 표준에서 비롯된 것입니다. 비트가 정확히 일치하더라도 "숫자가 아님"값은 절대 자신과 같지 않습니다. (이들이 IEEE-754에 반드시있는 것은 아니지만 여러 개의 "숫자가 아닌"값을 허용합니다.) 이것이 나타나는 이유이기도합니다. JavaScript의 다른 모든 값은 그 자체와 동일하며 NaN특별한 것입니다.

... x! == x에 대해 true를 반환하고 x! = x에 대해 false를 반환하는 JavaScript의 일부 값이 누락 되었습니까?

아냐 유일한 차이점 !==!=동일하게 피연산자의 유형을 얻기 위해 필요한 경우, 후자는 타입 강제 변환을 할 것입니다. 에서 x != x, 피연산자의 유형은 동일하며, 그래서 그것은 정확히 같은입니다 x !== x.

이것은 추상 평등 작업 의 정의 시작 부분에서 분명합니다 .

  1. ReturnIfAbrupt (x).
  2. ReturnIfAbrupt (y).
  3. Type (x)가 Type (y)와 같으면

    엄격한 평등 비교 x === y를 수행 한 결과를 반환합니다.

  4. ...

처음 두 단계는 기본 배관입니다. 실제로 첫 번째 단계 ==는 유형이 동일한 지 확인하고, 그렇다면 유형을 확인하는 ===것입니다.!=그리고 !==그것의 부정 버전입니다.

Flanagan 이을 (를) NaN위해 만 제공 하는 것이 정확하다면 x !== x, 우리는 또한NaN 마찬가지 줄 것이다 x != x.

사용하는 대부분의 자바 스크립트 프로그래머 기본 ===!==느슨한 운영 할 유형 강제 변환 주위에 몇 가지 함정을 피할 수 있지만,이 경우에는 엄격한 대 느슨한 운영자의 플래너의 사용으로 읽을 수있는 아무것도 없다.


나는 4.9.1 - Equality and Inequality Operators섹션 을 다시 읽었 으며 이것이 답 인 것 같습니다. ===비교의 요점은 다음 과 같습니다 If the two values have the same type, test them for strict equality as described above. If they are strictly equal, they are equal. If they are not strictly equal, they are not equal.
Giorgi Nakeuri

@GiorgiNakeuri : Flanagan의 책인 4.9.1이 무엇을 말하는지 잘 모르겠습니다. 그러나 그것은 기본적으로 위 사양의 인용문이 말하는 것을 말합니다.
TJ Crowder

2
공식적이고 정확한 방식으로 내 질문에 대답하기 때문에 이것을 받아들입니다. 설명 감사합니다!
Giorgi Nakeuri

1
@Moshe : "라이브 바인딩"은 무엇을 의미합니까? (이 용어는. 사양에 나타나지 않습니다)처럼 당신에게 평균 무언가를 GOTO 0의 예를 어디에 a실제로 기능하고 두 번 같은 값을 반환하지 않습니다? 즉, 같은 것은 아니다 에 대한 !==영업에 대해 무엇을 요구하다, 사실 일 것이다. 다른 값을 반환하는 함수 일뿐입니다. 각 호출마다 다른 값을 반환 할 수 있으므로 foo() !== foo()반드시 사실이 아닙니다 foo.
TJ Crowder

1
@Moshe 글쎄, 그것은 속성과 게터를 망칠 수있는 엄청난 방법입니다. 그러나 추가 간접 계층을 가진 GOTO 0의 예제와 거의 같은 것으로 보입니다.
JAB

37

NaN의의 목적을 위해 !=그리고!== 같은 일을한다.

그러나, 많은 프로그래머는 피 ==또는 !=자바 스크립트입니다. 예를 들어 Douglas Crockford 는 예상치 못한 혼란스러운 방식으로 동작하므로 JavaScript 언어 의 " 나쁜 부분 "으로 간주합니다 .

: 자바 스크립트는이 개 평등 사업자의 세트를 가지고 ===!==, 그들의 사악한 쌍둥이 ==!= . 좋은 것은 당신이 기대하는 방식으로 작동합니다.

... 나의 조언은 결코 사악한 쌍둥이를 사용하지 않는 것입니다. 대신, 항상 사용 ===하고 !==.


2
질문은 NaN에 관한 것이 아닙니다 (제목에도 불구하고). 문제는 "x! == x에 대해 true를 반환하고 x! = x에 대해 false를 반환하는 JavaScript의 일부 값이 누락 되었습니까?"입니다.
TJ Crowder

@TJCrowder 두 가지 질문이 있습니다. 첫 번째 질문은 "두 버전을 모두 사용하는 것이 안전합니까?"이며 두 버전이 동일하다는 대답이 있습니다. 나는 모든 것을 자세히 설명하는 당신의 "언더 더 (under-the-hood)"대답을 좋아한다.
jkdev

22

재미를 위해서, x그렇지는 NaN않지만 연산자가 다르게 행동 하는 인공적인 예를 보여 드리겠습니다 . 먼저 다음을 정의하십시오.

Object.defineProperty(
  self,
  'x',
  { get: function() { return self.y = self.y ? 0 : '0'; } }
);

그럼 우리는

x != x // false

그러나

x !== x // true

9
하아! :-) 그러나 그것은 foo() != foo()foo가 1에서 2를 반환하는 곳입니다. 예를 들어, 이 같지 않고 다른 값을 비교하는 것입니다.
TJ Crowder

2

나는 단지 전역 객체를 사용하지 않고 NaN생산 하는 것이 아니라고 지적하고 싶습니다 x !== x. 이 동작을 유발하는 영리한 방법이 많이 있습니다. 다음은 getter를 사용하는 것입니다.

var i = 0, obj = { get x() { return i++; }};
with(obj) // force dynamic context, this is evil. 
console.log(x === x); // false

다른 답변이 지적했듯이 ==유형 강제 변환을 수행하지만 다른 언어와 마찬가지로 표준에서-NaN은 계산 실패를 나타내며 좋은 이유로 자체와 동일하지 않습니다.

나를 넘어 어떤 이유로 사람들은 JS 로이 문제를 해결할 수 있지만 C, Java, C ++, C #, Python 등의 두 배가있는 대부분의 언어는이 정확한 동작을 나타내며 사람들은 그저 괜찮습니다.


2
예, @TJCrowder가 GOTO_0의 답변에 대한 의견에서 언급 한 것과 똑같습니까?
Giorgi Nakeuri

이러한 다른 언어로 모호한 유형 강제를 얻는 방법을 분명히 설명해 주시겠습니까?
chicocvenancio

0

때로는 이미지가 단어보다 낫습니다.이 표를 확인 하십시오. (이것은 내가 의견을 제시하는 이유입니다.

엄격한 평등 비교 (===)는 유형과 내용이 일치하는 경우에만 true를 반환한다는 것을 알 수 있습니다.

var f = "-1" === -1; //false

추상 동등 비교 (==)는 유형을 변환 한 다음 엄격하게 비교하여 내용 * 만 확인합니다.

var t = "-1" == -1; //true

ECMA 에 문의하지 않고 코드가 다음과 같이 true로 평가되는 방식으로 비교할 때 JavaScript가 고려하는 사항은 명확하지 않습니다 .

 var howAmISupposedToKnowThat = [] == false; //true
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.