Warum wird in JavaScript isNaN(" ")
ausgewertet false
, aber isNaN(" x")
ausgewertet true
?
Ich fahre numerische Operationen auf einem Texteingabefeld, und ich überprüfen , ob das Feld ist null
, ""
oder NaN
. Wenn jemand eine Handvoll Leerzeichen in das Feld eingibt, schlägt meine Validierung bei allen drei fehl, und ich bin verwirrt, warum die isNaN
Prüfung nicht bestanden wird.
javascript
nan
IVR Avenger
quelle
quelle
"" == false // true
undisNaN(" ") // false
Antworten:
JavaScript interpretiert eine leere Zeichenfolge als 0, wodurch der isNAN-Test nicht bestanden wird. Sie können zuerst parseInt für die Zeichenfolge verwenden, wodurch die leere Zeichenfolge nicht in 0 konvertiert wird. Das Ergebnis sollte dann fehlschlagen, isNAN.
quelle
isNaN(arg)
. 1) Konvertiere arg in Zahl, 2) Überprüfe, ob diese Zahl der numerische Wert istNaN
. Das hat mir geholfen, es besser zu verstehen.Sie werden das vielleicht überraschen oder auch nicht, aber hier ist ein Testcode, der Ihnen die Verrücktheit der JavaScript-Engine zeigt.
das bedeutet also, dass
und
aber
Habe Spaß :)
quelle
null
,""
und" "
mich selbst. Vielen Dank!Um es besser zu verstehen, öffnen Sie bitte das Ecma-Script-Spezifikations-PDF auf Seite 43 "ToNumber Applied to the String Type".
Wenn eine Zeichenfolge eine numerische Syntax hat, die eine beliebige Anzahl von Leerzeichen enthalten kann, kann sie in den Typ Zahl konvertiert werden. Leere Zeichenfolge wird mit 0 ausgewertet. Auch die Zeichenfolge 'Unendlichkeit' sollte geben
quelle
Versuchen Sie es mit:
Oder
quelle
Aus dem
MDN
Grund für das Problem, mit dem Sie konfrontiert sindMöglicherweise möchten Sie die folgende umfassende Antwort überprüfen, die auch den NaN-Vergleich auf Gleichheit abdeckt.
quelle
Ich denke, es liegt an der Eingabe von Javascript:
' '
wird in Null konvertiert, wohingegen'x'
nicht:quelle
Wenn Sie eine genaue isNumber-Funktion implementieren möchten, finden Sie hier eine Möglichkeit, dies mit Javascript zu tun : The Good Parts von Douglas Crockford [Seite 105]
quelle
Die nicht ganz richtige Antwort
Antonio Haleys hoch gelobte und akzeptierte Antwort hier geht falsch davon aus, dass dieser Prozess die
parseInt
Funktion von JavaScript durchläuft :Wir können diese Aussage leicht mit der Zeichenfolge widerlegen
"123abc"
:Damit können wir sehen, dass die JavaScript-
parseInt
Funktion"123abc"
als Zahl zurückgegeben wird123
, aber dieisNaN
Funktion sagt uns, dass dies"123abc"
keine Zahl ist.Die richtige Antwort
ECMAScript-262 definiert
isNaN
in Abschnitt 18.2.3, wie die Prüfung funktioniert .Die
ToNumber
Funktion, auf die verwiesen wird, ist auch in Abschnitt 7.1.3 von ECMAScript-262 definiert . Hier erfahren wir, wie JavaScript mit Strings umgeht, die an diese Funktion übergeben werden.Das erste Beispiel in der Frage ist eine Zeichenfolge, die nur Leerzeichen enthält. In diesem Abschnitt heißt es:
Die
" "
Beispielzeichenfolge wird daher in+0
eine Zahl konvertiert .Im selben Abschnitt heißt es auch:
Ohne alle in diesem Abschnitt enthaltenen Prüfungen zu zitieren,
" x"
fällt das in der Frage angegebene Beispiel in die obige Bedingung, da es nicht als a interpretiert werden kannStringNumericLiteral
." x"
wird daher in konvertiertNaN
.quelle
Ich bin mir nicht sicher warum , aber um das Problem zu umgehen, können Sie vor dem Überprüfen immer Leerzeichen kürzen. Sie möchten das wahrscheinlich trotzdem tun.
quelle
Die Funktion
isNaN("")
führt einen Zwang vom Typ String zu Number ausECMAScript 3-5 definiert die folgenden Rückgabewerte für den Operatortyp:
Wickeln Sie unseren Test besser in einen Funktionskörper:
Diese Funktion ist nicht auf Testvariablen intented Typ , stattdessen testet er den erzwungener Wert . Zum Beispiel werden Boolesche Werte und Zeichenfolgen zu Zahlen gezwungen. Vielleicht möchten Sie diese Funktion als aufrufen
isNumberCoerced()
Wenn Sie nicht nach anderen Typen als Zeichenfolge und Nummer testen müssen, wird möglicherweise das folgende Snippet als Teil einer Bedingung verwendet:
quelle
Ich empfehle Ihnen, die folgende Funktion zu verwenden, wenn Sie wirklich überprüfen möchten, ob es sich um eine Ganzzahl handelt:
quelle
Das
isNaN(" ")
ist falsch, ist Teil des verwirrenden Verhaltens derisNaN
globalen Funktion aufgrund ihres Zwangs von Nicht-Zahlen zu einem numerischen Typ.Von MDN :
Beachten Sie auch, dass es mit ECMAScript 6 jetzt auch das gibt
Number.isNaN
Methode gibt, die laut MDN:Unglücklicherweise :
Sogar die ECMAScript 6-
Number.isNaN
Methode hat ihre eigenen Probleme, wie im Blog-Beitrag beschrieben - Behebung des hässlichen JavaScript- und ES6-NaN-Problems .quelle
Die
isNaN
Funktion erwartet eine Zahl als Argument, sodass Argumente eines anderen Typs (in Ihrem Fall eine Zeichenfolge) in Zahl konvertiert werden, bevor die eigentliche Funktionslogik ausgeführt wird. (Beachten Sie, dassNaN
auch ein Wert vom Typ Nummer ist!)Übrigens. Dies gilt für alle integrierten Funktionen. Wenn sie ein Argument eines bestimmten Typs erwarten, wird das tatsächliche Argument mithilfe der Standardkonvertierungsfunktionen konvertiert. Es gibt Standardkonvertierungen zwischen allen Basistypen (Bool, String, Nummer, Objekt, Datum, Null, undefiniert).
Die Standardkonvertierung für
String
toNumber
kann explizit mit aufgerufen werdenNumber()
. So können wir das sehen:Number(" ")
bewertet zu0
Number(" x")
bewertet zuNaN
Vor diesem Hintergrund ist das Ergebnis der
isNaN
Funktion völlig logisch!Die eigentliche Frage ist, warum die Standardkonvertierung von Zeichenfolgen in Zahlen so funktioniert. Die Konvertierung von Zeichenfolgen in Zahlen ist eigentlich dazu gedacht, numerische Zeichenfolgen wie "123" oder "17.5e4" in die entsprechenden Zahlen umzuwandeln. Die Konvertierung überspringt zuerst das anfängliche Leerzeichen (also ist "123" gültig) und versucht dann, die Reste als Zahl zu analysieren. Wenn es nicht als Zahl analysiert werden kann ("x" nicht), ist das Ergebnis NaN. Es gibt jedoch die explizite Sonderregel, dass eine Zeichenfolge, die leer ist oder nur Leerzeichen enthält, in 0 konvertiert wird. Dies erklärt also die Konvertierung.
Referenz: http://www.ecma-international.org/ecma-262/5.1/#sec-9.3.1
quelle
Ich habe diese kurze kleine Funktion geschrieben, um dieses Problem zu lösen.
Es wird einfach nach Zeichen gesucht, die nicht numerisch (0-9), nicht '-' oder '.' Und nicht undefiniert, null oder leer sind, und es wird true zurückgegeben, wenn keine Übereinstimmungen vorhanden sind. :) :)
quelle
Wie bereits erläutert
isNaN
, zwingt die Funktion die leere Zeichenfolge vor der Validierung in eine Zahl und ändert so eine leere Zeichenfolge in 0 (was eine gültige Zahl ist). Ich habe jedoch festgestellt, dass dieparseInt
Funktion zurückgegeben wird,NaN
wenn versucht wird, eine leere Zeichenfolge oder eine Zeichenfolge mit nur Leerzeichen zu analysieren. Als solche scheint die folgende Kombination gut zu funktionieren:if ( isNaN(string) || isNaN(parseInt(string)) ) console.log('Not a number!');
Diese Prüfung funktioniert für positive Zahlen, negative Zahlen und Zahlen mit einem Dezimalpunkt. Ich glaube, sie deckt alle gängigen numerischen Fälle ab.
quelle
NaN
! == "keine Zahl"NaN
ist ein Wert vom Typ NummerDies ist eine Definition von isNaN () in ECMAScript
Versuchen Sie, einen beliebigen Wert in Zahl umzuwandeln.
Wenn Sie feststellen möchten, ob der Wert lautet
NaN
, sollten Sie zunächst versuchen, ihn in einen Zahlenwert umzuwandeln.quelle
Diese Funktion schien in meinen Tests zu funktionieren
quelle
return !(s === "" || s === null || parseInt(s) == 'NaN');
Wie wäre es mit
quelle
Die in JavaScript integrierte isNaN- Funktion ist - wie standardmäßig zu erwarten - ein "Dynamic Type Operator". Daher alle Werte, die (während des DTC-Prozesses) ein einfaches true | ergeben können falsch wie
"", " ", " 000"
, kann nicht NaN sein.Dies bedeutet, dass das angegebene Argument zunächst wie folgt konvertiert wird :
Erläuterung:
In der obersten Zeile des Funktionskörpers versuchen wir (zuerst), das Argument erfolgreich in ein Zahlenobjekt umzuwandeln. Und (zweitens) mit dem Punktoperator entfernen wir - zu unserer eigenen Bequemlichkeit - sofort den primitiven Wert des erstellten Objekts.
In der zweiten Zeile nehmen wir den im vorherigen Schritt erhaltenen Wert und den Vorteil der Tatsache, dass NaN mit nichts im Universum gleich ist, nicht einmal mit sich selbst, z. B.:
NaN == NaN >> false
Um es endgültig (wegen Ungleichheit) mit sich selbst zu vergleichen .Auf diese Weise liefert die Funktionsrückgabe nur dann true , wenn und nur wenn die angegebene Argumentrückgabe ein fehlgeschlagener Konvertierungsversuch in ein Zahlenobjekt ist, dh eine Zahl ohne Zahl; zB NaN.
isNaNstatic ()
Für einen Operator vom statischen Typ können wir jedoch - falls erforderlich und bei Bedarf - eine weitaus einfachere Funktion schreiben, z.
Vermeiden Sie den DTC insgesamt, damit das Argument false zurückgibt, wenn es nicht explizit eine NaN-Nummer ist. Testen Sie daher gegen Folgendes:
isNaNStatic(" x"); // will return false
weil es immer noch eine Schnur ist.Allerdings:
isNaNStatic(1/"x"); // will of course return true.
wie zum BeispielisNaNStatic(NaN); >> true
.Aber im Gegensatz dazu
isNaN
ist das,isNaNStatic("NaN"); >> false
weil es (das Argument) eine gewöhnliche Zeichenfolge ist.ps: Die statische Version von isNaN kann in modernen Codierungsszenarien sehr nützlich sein. Und es kann sehr wohl einer der Hauptgründe sein, warum ich mir die Zeit genommen habe, dies zu veröffentlichen.
Grüße.
quelle
isNAN(<argument>)
ist eine Funktion, um festzustellen, ob das angegebene Argument eine unzulässige Zahl ist.isNaN
typisiert die Argumente in den Typ Zahl. Wenn Sie überprüfen möchten, ob das Argument numerisch ist oder nicht? Bitte verwenden Sie die$.isNumeric()
Funktion in jQuery.Das heißt, isNaN (foo) entspricht isNaN (Number (foo)). Es akzeptiert aus offensichtlichen Gründen alle Zeichenfolgen mit allen Ziffern als Zahlen. Zum Beispiel.
quelle
ich benutze das
quelle
Wenn , wenn bestimmte Zeichenfolge - Wert mit Leerzeichen Überprüfung oder
" "
wirdisNaN
vielleicht versuchen Zeichenfolge Validierung durchgeführt werden , beispielsweise:// value = "123 " if (value.match(/\s/) || isNaN(value)) { // do something }
quelle