Dieser Code in JS gibt mir ein Popup mit der Aufschrift "Ich denke, Null ist eine Zahl", was ich etwas störend finde. Was vermisse ich?
if (isNaN(null)) {
alert("null is not a number");
} else {
alert("i think null is a number");
}
Ich verwende Firefox 3. Ist das ein Browser-Fehler?
Andere Tests:
console.log(null == NaN); // false
console.log(isNaN("text")); // true
console.log(NaN == "text"); // false
Das Problem scheint also kein exakter Vergleich mit NaN zu sein?
Bearbeiten: Nachdem die Frage beantwortet wurde, habe ich meinen Beitrag bereinigt, um eine bessere Version für das Archiv zu erhalten. Dies macht jedoch einige Kommentare und sogar einige Antworten etwas unverständlich. Beschuldigen Sie nicht ihre Autoren. Unter den Dingen, die ich geändert habe, war:
- Es wurde eine Notiz entfernt, die besagt, dass ich die Überschrift an erster Stelle durcheinander gebracht habe, indem ich ihre Bedeutung zurückgesetzt habe
- Frühere Antworten zeigten, dass ich nicht klar genug darlegte, warum ich das Verhalten für seltsam hielt, und fügte daher die Beispiele hinzu, die eine Zeichenfolge überprüfen und einen manuellen Vergleich durchführen.
javascript
Hanno Fietz
quelle
quelle
Antworten:
Ich glaube, der Code versucht zu fragen: "
x
Ist numerisch?" mit dem konkreten Fall hier vonx = null
. Die FunktionisNaN()
kann verwendet werden, um diese Frage zu beantworten, bezieht sich jedoch semantisch speziell auf den WertNaN
. Aus Wikipedia fürNaN
:In den meisten Fällen denken wir, dass die Antwort auf "ist null numerisch?" sollte nein sein. Ist
isNaN(null) == false
jedoch semantisch korrekt, da diesnull
nicht der Fall istNaN
.Hier ist die algorithmische Erklärung:
Die Funktion
isNaN(x)
versucht, den übergebenen Parameter in eine Zahl 1 (äquivalent zuNumber(x)
) umzuwandeln , und testet dann, ob der Wert gleich istNaN
. Wenn der Parameter nicht in eine Zahl konvertiert werden kann,Number(x)
wirdNaN
2 zurückgegeben . Wenn daher die Konvertierung eines Parametersx
in eine Zahl erfolgtNaN
, wird true zurückgegeben. Andernfalls wird false zurückgegeben.So in dem speziellen Fall
x = null
,null
wird auf die Zahl umgewandelt 0, (versuchen Sie die BewertungNumber(null)
und sehen , dass es 0 zurückgibt,) undisNaN(0)
gibt false zurück. Eine Zeichenfolge, die nur aus Ziffern besteht, kann in eine Zahl konvertiert werden, und isNaN gibt auch false zurück. Eine Zeichenfolge (zB'abcd'
) , die nicht in eine Zahl umgewandelt werden kann , wird dazu führen ,isNaN('abcd')
true zurück, und zwar weilNumber('abcd')
RenditenNaN
.Zusätzlich zu diesen offensichtlichen Randfällen sind die numerischen Standardgründe für die Rückgabe von NaN wie 0/0.
Bei den scheinbar inkonsistenten Gleichheitstests, die in der Frage gezeigt werden, wird das Verhalten von
NaN
so spezifiziert, dass jeder Vergleichx == NaN
falsch ist, unabhängig vom anderen Operanden, einschließlich sichNaN
selbst 1 .quelle
NaN !== NaN
. Also, ich denke, es ist nicht ganz richtig zu sagen,Number('abcd') == NaN
weilNumber('abcd')
esNaN
aber nicht gleich istNaN
. Ich liebe JavaScript.Number('abcd')
istNaN
aber ich angedeutet , dass es für die Gleichstellung wahr prüft, was nicht der Fall ist. Ich werde es bearbeiten.isNaN
und soNumber
gestaltet sind, um sich so zu verhalten.null
auf0
nur (zumindest in diesem Zusammenhang) tritt in derisNaN()
Funktion, die ihr Argument nötigt.Ich bin gerade selbst auf dieses Problem gestoßen.
Für mich ist der beste Weg, isNaN zu verwenden, so
isNaN(parseInt(myInt))
am Beispiel von Phyzome von oben,
(Ich habe das Ergebnis entsprechend der Eingabe ausgerichtet und hoffe, dass es leichter zu lesen ist.)
Das scheint mir besser zu sein.
quelle
myInt
= "123d".parseInt
konvertiert "123d" in 123, wodurch derisNaN
Test nicht bestanden wird.isNaN(parseInt(str,10)) || isNaN(Number())
. Übrigens - für mich ist esparseInt
in Ordnung, "123d" als gültige Zahl zu betrachten , da ich laufen muss, um den numerischen Wert der Zeichenfolge zu verwenden. Ich sehe jedoch die Notwendigkeit, dieses Szenario ebenfalls zu erkennen.(Mein anderer Kommentar verfolgt einen praktischen Ansatz. Hier ist die theoretische Seite.)
Ich habe den ECMA 262-Standard nachgeschlagen, den Javascript implementiert. Ihre Spezifikation für isNan:
Abschnitt 9.3 gibt das Verhalten von an
ToNumber
(dies ist keine aufrufbare Funktion, sondern eine Komponente des Typkonvertierungssystems). Um die Tabelle zusammenzufassen, können bestimmte Eingabetypen ein NaN erzeugen. Dies sind Typundefined
, Typnumber
(aber nur der WertNaN
), jedes Objekt, dessen primitive Darstellung es istNaN
, und jedes Objektstring
, das nicht analysiert werden kann. Diese Blätterundefined
,NaN
,new Number(NaN)
und die meisten Saiten.Jede solche Eingabe, die
NaN
als Ausgabe erzeugtToNumber
wird, wenn sie an übergeben wird, erzeugt eine,true
wenn sie angeführt wirdisNaN
. Danull
erfolgreich in eine Zahl konvertiert werden kann, wird nicht produzierttrue
.Und deshalb.
quelle
Das ist in der Tat beunruhigend. Hier ist eine Reihe von Werten, die ich getestet habe:
Es wertet (in der Firebug-Konsole) Folgendes aus:
Wenn ich
x.map(isNaN)
anrufe (um isNaN für jeden Wert aufzurufen), erhalte ich:Fazit:
isNaN
Sieht ziemlich nutzlos aus! ( Bearbeiten : Außer es stellt sich heraus, dass isNaN nur über Number definiert ist. In diesem Fall funktioniert es einwandfrei - nur mit einem irreführenden Namen.)Im Übrigen sind hier die Arten dieser Werte:
quelle
Null ist nicht NaN, und ein String ist nicht NaN. isNaN () teste einfach, ob du wirklich das NaN-Objekt hast.
quelle
Ich bin mir nicht ganz sicher, wenn es um JS geht, aber ich habe ähnliche Dinge in anderen Sprachen gesehen, und das liegt normalerweise daran, dass die Funktion nur prüft, ob null genau gleich NaN ist (dh null === NaN wäre falsch). Mit anderen Worten, es ist nicht so, dass es denkt, dass null tatsächlich eine Zahl ist, sondern dass null nicht NaN ist. Dies liegt wahrscheinlich daran, dass beide in JS unterschiedlich dargestellt werden, so dass sie nicht genau gleich sind, genauso wie 9! == '9'.
quelle
In ES5 wird definiert als return
isNaN (number)
true, wenn das Argument zu NaN gezwungen wird, und andernfalls false.Und siehe Die abstrakte Operation ToNumber convertion Tabelle . So ist es intern js Motor bewerten
ToNumber(Null)
ist+0
, dann schließlichisNaN(null)
istfalse
quelle
Hinweis:
Der Operator == führt eine Typkonvertierung durch, === jedoch nicht.
Douglas Crockfords Website , ein Yahoo! JavaScript-Evangelist ist eine großartige Ressource für solche Dinge.
quelle