Przede wszystkim chcę wspomnieć, że umiem isNaN()
i Number.isNaN()
pracuję. Czytam The Definite Guide Davida Flanagana i podaje on przykład, jak sprawdzić, czy wartość wynosi NaN
:
x !== x
Spowoduje to true
wtedy i tylko wtedy, gdy x
jest NaN
.
Ale teraz mam pytanie: dlaczego używa ścisłego porównania? Ponieważ na to wygląda
x != x
zachowuje się w ten sam sposób. Czy używanie obu wersji jest bezpieczne, czy też brakuje mi pewnych wartości w JavaScript, które zostaną zwrócone true
dla x !== x
i false
dla x != x
?
javascript
nan
Giorgi Nakeuri
źródło
źródło
!==
czeki od!=
czeków. O ile mi wiadomo, nie ma innej wartości, w którejx != x
. Ale są dwie odrębne grupy programistów JavaScript: ci, którzy wolą!=
i ci, którzy wolą!==
, czy to ze względu na szybkość, przejrzystość, ekspresję itp.NaN
nie jest unikalnym typem, to liczba. To wyjątkowa wartość, która nie jest sobie równa.===
z NaN, aby podkreślić, że NaN nie jest sobie równy. Nie jest „zły”, robi to jako ćwiczenie dydaktyczne, demonstrując, że to nie działa.Odpowiedzi:
Po pierwsze, chciałbym zaznaczyć, że
NaN
jest to bardzo szczególna wartość: z definicji nie jest sobie równa. Wynika to ze standardu IEEE-754, z którego korzystają numery JavaScript. Wartość „nie jest liczbą” nigdy nie jest równa sobie, nawet jeśli bity są dokładnie zgodne. (Które niekoniecznie w IEEE-754, zezwala na wiele różnych wartości „nie jest liczbą”). Dlatego właśnie to się pojawia; wszystkie inne wartości w JavaScript są sobie równe,NaN
są po prostu wyjątkowe.Nie, nie jesteś. Jedyna różnica między
!==
i!=
polega na tym, że ten ostatni wykona wymuszenie typu, jeśli to konieczne, aby uzyskać takie same typy operandów. Wx != x
programie typy operandów są takie same, więc jest dokładnie takie samo, jakx !== x
.Jest to jasne od początku definicji Operacji Abstrakcyjnej Równości :
Pierwsze dwa kroki to podstawowa instalacja hydrauliczna. W efekcie pierwszym krokiem
==
jest sprawdzenie, czy typy są takie same, a jeśli tak, to===
zamiast tego zrobić .!=
i!==
są po prostu zanegowanymi wersjami tego.Więc jeśli Flanagan ma rację, że tylko
NaN
da prawdęx !== x
, możemy być pewni, że prawdą jest również to, że tylkoNaN
da prawdęx != x
.Wielu programistów JavaScript domyślnie używa
===
i!==
unika pewnych pułapek związanych z wymuszaniem typów, jakie stosują operatory loose, ale nie ma nic do czytania w używaniu przez Flanagana operatora ścisłego i luźnego w tym przypadku.źródło
4.9.1 - Equality and Inequality Operators
sekcję i wydaje się, że to jest odpowiedź. Kluczową kwestią dla===
porównania jest: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
.a
rzeczywistości jest funkcją i nie zwraca dwukrotnie tej samej wartości? To nie to samo, co wartość, która!==
byłaby prawdziwa, o co pytał PO. To po prostu funkcja, która zwraca różne wartości.foo() !== foo()
nie jest też koniecznie prawdą, ponieważfoo
może zwracać różne wartości przy każdym wywołaniu.Dla celów NaN
!=
i!==
zrób to samo.Jednak wielu programistów unika
==
lub!=
używa JavaScript. Na przykład Douglas Crockford uważa je za „ złe strony ” języka JavaScript, ponieważ zachowują się w nieoczekiwany i mylący sposób:źródło
Dla zabawy pozwólcie, że pokażę wam sztuczny przykład, gdzie go
x
nie ma,NaN
ale operatorzy i tak zachowują się inaczej. Najpierw zdefiniuj:Następnie mamy
ale
źródło
foo() != foo()
foo zwraca 1, a potem 2. Np. Wartości nie są takie same, po prostu porównuje różne wartości.Chcę tylko podkreślić, że
NaN
nie jest jedyną rzeczą, która produkujex !== x
bez użycia obiektu globalnego. Istnieje wiele sprytnych sposobów wywołania tego zachowania. Oto jeden z pobierających:Jak wskazują inne odpowiedzi,
==
wykonuje koersję typów, ale tak jak w innych językach i par standard - NaN wskazuje na błąd obliczeniowy iz dobrych powodów nie jest sobie równy.Z jakiegoś niezrozumiałego powodu ludzie uważają, że jest to problem z JS, ale większość języków, które mają dublety (a mianowicie C, Java, C ++, C #, Python i inne) wykazuje dokładnie to zachowanie i ludziom po prostu nie przeszkadza.
źródło
Ponieważ czasami obrazy są lepsze niż słowa, sprawdź tę tabelę (dlatego uważam, że jest to odpowiedź, zamiast komentarza, ponieważ staje się ona lepiej widoczna).
Możesz tam zobaczyć, że ścisłe porównanie równości (===) zwraca prawdę tylko wtedy, gdy typ i zawartość są zgodne, więc
Podczas gdy abstrakcyjne porównanie równości (==) sprawdza tylko zawartość *, konwertując typy, a następnie ściśle je porównując:
Chociaż nie jest jasne, bez konsultacji z ECMA , co JavaScript bierze pod uwagę podczas porównywania, w taki sposób, że poniższy kod ocenia jako prawdziwy.
źródło