Dlaczego w JavaScript isNaN(" ")
ocenia się na false
, ale isNaN(" x")
ocenia na true
?
Mam wykonywania operacji numerycznych na polu tekstowym, a ja sprawdzenie, czy pole jest null
, ""
albo NaN
. Kiedy ktoś wpisze w to pole kilka spacji, moja walidacja kończy się niepowodzeniem we wszystkich trzech i jestem zdezorientowany, dlaczego przeszedł isNaN
kontrolę.
javascript
nan
IVR Avenger
źródło
źródło
"" == false // true
orazisNaN(" ") // false
Odpowiedzi:
JavaScript interpretuje pusty ciąg jako 0, co następnie kończy się niepowodzeniem w teście isNAN. Możesz najpierw użyć parseInt na łańcuchu, co nie spowoduje konwersji pustego ciągu na 0. Wynik powinien wtedy zakończyć się niepowodzeniem toNAN.
źródło
isNaN(arg)
. 1) Zamień argument na liczbę, 2) Sprawdź, czy ta liczba jest wartością liczbowąNaN
. To pomogło mi lepiej to zrozumieć.Może się to wydawać zaskakujące, ale może nie, ale oto kod testowy, który pokaże ci zwariowanie silnika JavaScript.
więc to znaczy, że
i
ale
Baw się dobrze :)
źródło
null
,""
i" "
ja. Dzięki!Aby lepiej to zrozumieć, otwórz specyfikację Ecma-Script pdf na stronie 43 „ToNumber zastosowany do typu ciągu”
jeśli ciąg ma składnię numeryczną, która może zawierać dowolną liczbę białych znaków, można go przekonwertować na typ Number. Pusty łańcuch ma wartość 0. Również powinien dać ciąg „Nieskończoność”
źródło
Spróbuj użyć:
Lub
źródło
Z
MDN
powodu problemu, przed którym stoiszMożesz chcieć sprawdzić następującą kompleksową odpowiedź, która obejmuje również porównanie NaN dla równości.
źródło
Myślę, że to z powodu pisania w Javascript:
' '
jest konwertowane na zero, a'x'
nie:źródło
Jeśli chcesz zaimplementować dokładną funkcję isNumber, oto jeden ze sposobów na zrobienie tego z Javascript: The Good Parts autorstwa Douglasa Crockforda [strona 105]
źródło
Odpowiedź nie do końca poprawna
Bardzo pozytywna i akceptowana tutaj odpowiedź Antonio Haleya zakłada błędne założenie, że ten proces przechodzi przez
parseInt
funkcję JavaScript :Możemy łatwo obalić to stwierdzenie za pomocą łańcucha
"123abc"
:Dzięki temu możemy zobaczyć, że
parseInt
funkcja JavaScript zwraca"123abc"
jako liczbę123
, ale jejisNaN
funkcja mówi nam, że"123abc"
tak nie jest jest liczbą.Poprawna odpowiedź
ECMAScript-262 definiuje sposób działania
isNaN
sprawdzenia w sekcji 18.2.3 .Te
ToNumber
odniesienia funkcją jest również zdefiniowane w ECMAScript-262 w sekcji 7.1.3 . Tutaj dowiadujemy się, jak JavaScript obsługuje ciągi znaków przekazywane do tej funkcji.Pierwszy przykład podany w pytaniu to łańcuch zawierający tylko znaki odstępu. Ta sekcja stwierdza, że:
" "
Przykład łańcuch jest zatem przekształca się+0
, co jest liczbą.Ta sama sekcja stwierdza również:
Bez cytowania wszystkich kontroli zawartych w tej sekcji,
" x"
przykład podany w pytaniu mieści się w powyższym warunku, ponieważ nie może być interpretowany jako aStringNumericLiteral
." x"
jest zatem konwertowany naNaN
.źródło
Nie jestem pewien, dlaczego , ale aby obejść problem, zawsze można było skrócić spacje przed sprawdzeniem. Prawdopodobnie i tak chcesz to zrobić.
źródło
Funkcja
isNaN("")
wykonuje wymuszenie typu ciąg na liczbęECMAScript 3-5 definiuje następujące wartości zwracane dla operatora typeof:
Lepiej zawrzeć nasz test w treści funkcji:
Ta funkcja nie jest przeznaczona do testowania typu zmiennej , zamiast tego testuje wymuszoną wartość . Na przykład wartości logiczne i ciągi znaków są przekształcane na liczby, więc być może warto nazwać tę funkcję jako
isNumberCoerced()
jeśli nie ma potrzeby testowania typów innych niż ciąg i liczba , następujący fragment może zostać użyty jako część warunku:
źródło
Proponuję użyć następującej funkcji, jeśli naprawdę chcesz poprawnie sprawdzić, czy jest to liczba całkowita:
źródło
To
isNaN(" ")
jest fałsz jest częścią zagmatwanego zachowaniaisNaN
funkcji globalnej z powodu jej przymusu przekształcania nieliczbowych w typ liczbowy.Z MDN :
Zauważ również, że w ECMAScript 6 istnieje teraz również
Number.isNaN
metoda, która według MDN:Niestety :
Nawet
Number.isNaN
metoda ECMAScript 6 ma swoje własne problemy, które opisano w poście na blogu - Naprawianie brzydkiego problemu JavaScript i ES6 NaN .źródło
Plik
isNaN
Funkcja oczekuje numeru jako argument, więc argumenty innego rodzaju (w przypadku łańcuch) zostaną przekształcone w Number przed rzeczywista logika funkcja jest wykonywana. (Należy pamiętać, żeNaN
jest to również wartość typu Number!)Przy okazji. to jest wspólne dla wszystkich funkcji wbudowanych - jeśli oczekują argumentu określonego typu, rzeczywisty argument zostanie przekonwertowany przy użyciu standardowych funkcji konwersji. Istnieją standardowe konwersje między wszystkimi podstawowymi typami (bool, string, number, object, date, null, undefined).
Standardową konwersję for
String
doNumber
można wywołać jawnie za pomocąNumber()
. Widzimy więc, że:Number(" ")
ocenia do0
Number(" x")
ocenia doNaN
Biorąc to pod uwagę, wynik
isNaN
funkcji jest całkowicie logiczny!Prawdziwe pytanie brzmi, dlaczego standardowa konwersja ciągów na liczbę działa tak, jak to robi. Konwersja ciągów na liczby ma w rzeczywistości na celu konwersję ciągów liczbowych, takich jak „123” lub „17,5e4”, na równoważne liczby. Konwersja najpierw pomija początkowe białe znaki (więc „123” jest poprawne), a następnie próbuje przeanalizować resztę jako liczbę. Jeśli nie można jej analizować jako liczby („x” nie jest), to wynikiem jest NaN. Ale istnieje specjalna, wyraźna reguła, że ciąg, który jest pusty lub zawiera tylko białe znaki, jest konwertowany na 0. To wyjaśnia konwersję.
Źródła: http://www.ecma-international.org/ecma-262/5.1/#sec-9.3.1
źródło
Napisałem tę krótką funkcję, aby pomóc rozwiązać ten problem.
Po prostu sprawdza wszystkie znaki, które nie są liczbami (0-9), które nie są „-” ani „.”, I które nie są niezdefiniowane, puste lub puste i zwraca wartość „prawda”, jeśli nie ma dopasowań. :)
źródło
Jak wyjaśnili inni,
isNaN
funkcja przekształci pusty ciąg w liczbę przed jej walidacją, zmieniając w ten sposób pusty ciąg na 0 (co jest prawidłową liczbą). Jednak odkryłem, żeparseInt
funkcja zwróciNaN
podczas próby przeanalizowania pustego ciągu lub ciągu zawierającego tylko spacje. Jako taka wydaje się, że następująca kombinacja działa dobrze:if ( isNaN(string) || isNaN(parseInt(string)) ) console.log('Not a number!');
To sprawdzenie będzie działać dla liczb dodatnich, ujemnych i liczb z przecinkiem, więc uważam, że obejmuje wszystkie typowe przypadki liczbowe.
źródło
NaN
! == "nie jest liczbą"NaN
jest wartością typu liczbowegoto jest definicja isNaN () w ECMAScript
Spróbuj przekonwertować dowolną wartość na liczbę.
Jeśli chcesz ustalić, czy wartość jest równa
NaN
, powinieneś najpierw spróbować przekonwertować ją na wartość liczbową.źródło
Ta funkcja wydawała się działać w moich testach
źródło
return !(s === "" || s === null || parseInt(s) == 'NaN');
Co powiesz na
źródło
JavaScript wbudowanej isNaN funkcji, jest - jak należy oczekiwać domyślnie - „Dynamiczny Type Operator”. Dlatego wszystkie wartości, które (podczas procesu DTC) mogą dawać prostą prawdę | fałszywe, takie jak
"", " ", " 000"
, nie może być NaN.Oznacza to, że podany argument zostanie najpierw poddany konwersji, jak w:
Wyjaśnienie:
W górnym wierszu treści funkcji (najpierw) próbujemy pomyślnie przekształcić argument na obiekt liczbowy. I (drugi), za pomocą operatora kropki jesteśmy - dla własnej wygody - natychmiast zdzierając, prymitywny wartość tworzonego obiektu.
W drugim wierszu bierzemy wartość uzyskaną w poprzednim kroku oraz zaletę faktu, że NaN nie jest równe żadnemu we wszechświecie, nawet sobie, np:
NaN == NaN >> false
aby ostatecznie porównać ją (pod kątem nierówności) ze sobą .W ten sposób funkcja return zwróci wartość true tylko wtedy i tylko wtedy, gdy podany argument-return jest nieudaną próbą konwersji na obiekt liczbowy, tj. Liczbę niebędącą liczbą; np. NaN.
isNaNstatic ()
Jednak dla operatora typu statycznego - w razie potrzeby i kiedy potrzeba - możemy napisać znacznie prostszą funkcję, taką jak:
I całkowicie unikaj DTC, aby jeśli argument nie był jawnie liczbą NaN, zwrócił fałsz. Dlatego testowanie pod kątem:
isNaNStatic(" x"); // will return false
ponieważ nadal jest to ciąg.Jednak:
isNaNStatic(1/"x"); // will of course return true.
tak jak na przykładisNaNStatic(NaN); >> true
.Ale w przeciwieństwie do tego
isNaN
,isNaNStatic("NaN"); >> false
ponieważ to (argument) jest zwykłym ciągiem.ps: Statyczna wersja isNaN może być bardzo przydatna w nowoczesnych scenariuszach kodowania. I może to być jeden z głównych powodów, dla których nie spieszyłem się z opublikowaniem tego.
Pozdrowienia.
źródło
isNAN(<argument>)
jest funkcją, która mówi, czy dany argument jest niedozwoloną liczbą.isNaN
typekastruje argumenty do typu Number. Jeśli chcesz sprawdzić, czy argument jest numeryczny, czy nie? Proszę użyć$.isNumeric()
funkcji w jQuery.Oznacza to, że isNaN (foo) jest równoważne isNaN (Number (foo)). Z oczywistych powodów akceptuje wszystkie łańcuchy zawierające wszystkie cyfry jako liczby. Na przykład.
źródło
używam tego
źródło
Przy sprawdzaniu, czy pewnej wartości ciąg z odstępami lub
" "
jestisNaN
może próbować wykonać walidację ciąg, przykład:// value = "123 " if (value.match(/\s/) || isNaN(value)) { // do something }
źródło