Frage

Ich habe eine kurze Frage (hoffe ich!). In JS, warum tut isNaN(" ") auf falsch zu bewerten, aber isNaN(" x") bewerten, um wahr?

Ich fahre numerische Operationen auf einem Texteingabefeld, und bin zu überprüfen, ob das Feld Null ist, „“, oder NaN. Wenn jemand Typen eine Handvoll Räume in das Feld, nicht meine Validierung auf allen drei, und ich bin verwirrt, warum es wird über die isNAN überprüfen.

Danke!

War es hilfreich?

Lösung

JavaScript interpretiert eine leere Zeichenfolge als 0, der dann den isNAN Test fehlschlägt. Sie können zunächst auf die Saite verwenden ParseInt welche die leere Zeichenfolge zu 0. Das Ergebnis ist nicht konvertieren sollte dann isNAN versagen.

Andere Tipps

Sie können diese überraschend finden oder vielleicht auch nicht, aber hier ist einiger Test-Code Ihnen die wackyness der JavaScript-Engine zu zeigen.

document.write(isNaN("")) // false
document.write(isNaN(" "))  // false
document.write(isNaN(0))  // false
document.write(isNaN(null)) // false
document.write(isNaN(false))  // false
document.write("" == false)  // true
document.write("" == 0)  // true
document.write(" " == 0)  // true
document.write(" " == false)  // true
document.write(0 == false) // true
document.write(" " == "") // false

so bedeutet dies, dass

" " == 0 == false

und

"" == 0 == false

und

"" != " "

Viel Spaß:)

Um es besser zu verstehen, öffnen Sie bitte Ecma-Script spec pdf auf Seite 43 "ToNumber Applied zum String-Typ"

, wenn eine Zeichenfolge, die eine numerische Syntax hat, die eine beliebige Anzahl von Leerraumzeichen enthalten kann, kann es zu Zahlentyp konvertiert werden. Leere Zeichenfolge auswertet auf 0 Auch der String ‚Unendlich‘ geben soll

isNaN('Infinity'); // false

Versuchen Sie es mit:

alert(isNaN(parseInt("   ")));

oder

alert(isNaN(parseFloat("    ")));

MDN Grund für das Problem, das Sie stehen vor

  

Wenn das Argument der isNaN Funktion nicht vom Typ Zahl ist, wird der Wert zunächst in eine Zahl dazu gezwungen. Der resultierende Wert wird dann geprüft, um zu bestimmen, ob es NaN ist.

Sie können die folgende umfassende Antwort zu überprüfen, die auch den NaN Vergleich auf Gleichheit abdeckt.

  

Wie zu testen, ob ein JavaScript-Variable NaN ist

Ich denke, es ist wegen der Javascript typing: ' ' auf Null umgewandelt wird, während 'x' nicht:

alert(' ' * 1); // 0
alert('x' * 1); // NaN

Wenn Sie möchten, um eine genaue ISNUMBER Funktion implementieren, hier ist eine Möglichkeit, es von Javascript zu tun: The Good Parts von Douglas Crockford [Seite 105]

var isNumber = function isNumber(value) {
   return typeof value === 'number' && 
   isFinite(value);
}

Die Nicht-Ganz-Antwort zu korrigieren

Antonio Haleys sehr upvoted und Antwort akzeptiert hier macht eine falsche Annahme, dass dieser Prozess durch parseInt Funktion des JavaScript geht:

  

Sie parseInt auf der Saite verwenden können ... Das Ergebnis sollte dann isNAN versagen.

Wir können leicht diese Aussage mit der Zeichenfolge "123abc" entkräften:

parseInt("123abc")    // 123     (a number...
isNaN("123abc")       // true     ...which is not a number)

Mit diesem können wir sehen, dass JavaScript die parseInt Funktion "123abc" als die Nummer 123 zurück, doch seine isNaN Funktion sagt uns, dass "123abc" nicht eine Zahl.

Die richtige Antwort

ECMAScript-262 definiert, wie die isNaN Prüfung arbeitet in Abschnitt 18.2.3 .

  

18.2.3 isNaN (Zahl)

     

Die isNaN Funktion ist das %isNaN% intrinsische Objekt. Wenn die isNaN Funktion mit einem Argument Nummer aufgerufen wird, werden die folgenden Schritte unternommen:

     
      
  1. Lassen Sie num sein? ToNumber(number).
  2.   
  3. Wenn num NaN ist, kehren true.
  4.   
  5. Ansonsten Rückgabe false.
  6.   

Die ToNumber Funktion verweist es wird auch in ECMAScript-262 der Abschnitt 7.1.3 . Hier bekommen wir gesagt, wie JavaScript Griffe Strings, die in dieser Funktion übergeben werden.

Das erste in der Frage gegebene Beispiel ist eine Zeichenkette nur Leerzeichen enthält. In diesem Abschnitt heißt es:

  

Ein StringNumericLiteral, die leer oder enthält nur Leerraum umgewandelt +0.

Das " " Beispiel String wird daher umgewandelt +0, was eine Zahl ist.

Der gleiche Abschnitt auch lautet:

  

Wenn die Grammatik der String als Erweiterung von StringNumericLiteral nicht interpretieren kann, dann ist das Ergebnis von ToNumber ist NaN.

Ohne in diesem Abschnitt enthalten alle Prüfungen unter Angabe der " x" Beispiel in der Frage gegeben fällt in der obigen Bedingung, da es nicht als StringNumericLiteral interpretiert werden kann. " x" wird deshalb umgewandelt NaN.

Ich bin nicht sicher, Warum , sondern um das Problem zu bekommen Sie immer Leerzeichen trimmen könnten vor dem Einchecken. Sie wollen wahrscheinlich, dass auf jeden Fall tun.

Die Funktion isNaN("") führt eine String Nummer Zwang geben

ECMAScript 3-5 definiert die folgenden Rückgabewerte für die typeof-Operator:

  • undefined
  • Objekt (null, Objekte, Arrays)
  • boolean
  • number
  • string
  • Funktion

Besser unseren Test in einem Funktionskörper wickeln:

function isNumber (s) {
    return typeof s == 'number'? true
           : typeof s == 'string'? (s.trim() === ''? false : !isNaN(s))
           : (typeof s).match(/object|function/)? false
           : !isNaN(s)
}

Diese Funktion intented nicht Variable type zu testen, statt es testet den dazu gezwungen Wert . So werden zum Beispiel booleans und Strings in Zahlen dazu gezwungen, so vielleicht können Sie diese Funktion als isNumberCoerced() anrufen möchten

, wenn es keine Notwendigkeit, zu testen für Typen andere als string und Zahl , dann wird der folgende Ausschnitt könnte als Teil einer Bedingung verwendet werden :

if (!isNaN(s) && s.toString().trim()!='') // 's' can be boolean, number or string
    alert("s is a number")

Ich schlage vor, Sie die folgende Funktion zu verwenden, wenn Sie wirklich eine richtige Kontrolle wollen, wenn es eine ganze Zahl ist:

function isInteger(s)
{
   return Math.ceil(s) == Math.floor(s);
}

Die isNaN(" ") falsch ist Teil des verwirrenden Verhaltens der isNaN globalen Funktion aufgrund seines Zwang von Nicht-Zahlen in einen numerischen Typ ist.

MDN :

  

Seit den frühesten Versionen der isNaN Funktionsspezifikation, sein Verhalten für nicht-numerische Argumente hat verwirrend. Wenn das Argument der isNaN Funktion nicht vom Typ Zahl ist, wird der Wert zunächst in eine Zahl dazu gezwungen. Der resultierende Wert wird dann geprüft, um zu bestimmen, ob es NaN ist. So für nicht Zahlen, die, wenn sie in einem gültigen nicht-NaN numerischen Wert (insbesondere die leere Zeichenfolge und boolean Primitiven, die, wenn sie erzwungener numerische Werte Null oder Eins geben) auf numerische Art Ergebnis dazu gezwungen, die „falsch“ zurückgegebene Wert unerwartet sein kann; die leere Zeichenkette, zum Beispiel, ist sicherlich „keine Zahl.“

Beachten Sie auch, dass mit ECMAScript 6, gibt es auch jetzt ist die Number.isNaN Methode, die nach MDN:

  

Im Vergleich zur globalen isNaN() Funktion, Number.isNaN() leidet nicht das Problem mit Gewalt der Parameter auf eine Zahl zu konvertieren. Das bedeutet, es nun sicher ist, Wert zu übergeben, die normalerweise umwandeln würden NaN, ist aber nicht wirklich der gleiche Wert wie NaN. Dies bedeutet auch, dass nur Werte der Typnummer, die auch NaN sind, kehren true.

Leider :

Auch die ECMAScript 6 Number.isNaN Methode hat ihre eigenen Probleme, wie im Blog-Post skizziert - Befestigung des hässlichen JavaScript und ES6 NaN Problem .

Als andere erläuterten die Funktion isNaN die leere Zeichenfolge in eine Zahl zwingen, bevor es Validieren, wodurch eine leere Zeichenfolge in 0 zu ändern (was eine gültige Zahl ist). Ich fand jedoch, dass die parseInt Funktion NaN zurückkehren wird beim Versuch, eine leere Zeichenfolge oder eine Zeichenfolge mit nur Leerzeichen zu analysieren. Als solche ist die folgende Kombination gut zu funktionieren scheint:

if ( isNaN(string) || isNaN(parseInt(string)) ) console.log('Not a number!');

Diese Prüfung wird für positive Zahlen arbeitet, negative Zahlen und Zahlen mit einem Komma, so dass ich glaube, dass es alle gängigen numerischen Fälle abdeckt.

Diese Funktion schien in meinen Tests arbeiten

function isNumber(s) {
    if (s === "" || s === null) {
        return false;
    } else {
        var number = parseInt(s);
        if (number == 'NaN') {
            return false;
        } else {
            return true;
        }
    }
}

Was ist

function isNumberRegex(value) {        
    var pattern = /^[-+]?\d*\.?\d*$/i;
    var match = value.match(pattern);
    return value.length > 0 && match != null;
}

Die isNaN Funktion erwartet eine Zahl als Argument, so Argumente eines anderen Typs (in Ihrem Fall ein String) wird eine Zahl umgewandelt werden vor die tatsächliche Funktionslogik durchgeführt wird. (Beachten Sie, dass NaN ist auch ein Wert vom Typ Zahl!)

Btw. das ist nicht unüblich für alle integrierte Funktionen - wenn sie ein Argument eines bestimmten Typs erwarten, wird das tatsächliche Argument unter Verwendung der Standard-Konvertierungsfunktionen umgewandelt werden. Es gibt Standard-Konvertierungen zwischen allen Grundtypen (Bool, String, Anzahl, Objekt, Datum, null, nicht definiert.)

Die Standardkonvertierung für String zu Number mit Number() explizit aufgerufen werden. So können wir sehen, dass:

  • Number(" ") ausgewertet 0
  • Number(" x") ausgewertet NaN

Dieses Anbetracht das Ergebnis der isNaN Funktion ist völlig logisch!

Die eigentliche Frage ist, warum die Standard-String-to-Nummer Konvertierung funktioniert wie es funktioniert. Die String-to-Nummer Umwandlung ist wirklich gedacht numerische Zeichenfolge zu konvertieren wie „123“ oder „17.5e4“ auf die entsprechenden Zahlen. Die Umwandlung erste anfängliche Leerüberspringt (so „123“ gelten), und versucht dann, die Reste als Zahl zu parsen. Wenn es nicht parseable als Zahl ist ( „x“ ist nicht), dann ist das Ergebnis NaN. Aber es ist die explizite Sonderregel, die eine Zeichenkette, die leer oder nur Leerzeichen sind umgewandelt zu 0, so dass dies die Umwandlung erklärt.

Referenz: http: //www.ecma-international .org / ECMA-262 / 5,1 / # sec-9.3.1

Ich schrieb diese schnelle kleine Funktion zu helfen, dieses Problem zu lösen.

function isNumber(val) {
     return (val != undefined && val != null && val.toString().length > 0 && val.toString().match(/[^0-9\.\-]/g) == null);
};

Es prüft nur für alle Zeichen, die nicht numerisch (0-9) sind, die nicht sind ‚-‘ ‚‘ oder, und das ist nicht definiert, null oder leer und true zurück, wenn es keine Übereinstimmungen gibt. :)

Die JavaScript Built-in isNaN Funktion, ist - wie sollte standardmäßig zu erwarten - ein "Dynamic Typ Operator". Daher werden alle Werte, die (während des DTC-Prozess) ein einfaches wahr ergeben können | falsch wie "", " ", " 000" kann NaN nicht sein.

Was bedeutet, dass die Argument geliefert wird zuerst durchläuft eine Umwandlung wie in:

function isNaNDemo(arg){
   var x = new Number(arg).valueOf();
   return x != x;
}

Erklärung:

In der oberen Zeile der Funktion Körper, wir sind (erste) versuchen, erfolgreich das Argument in eine Anzahl Objekt zu konvertieren. Und (zweite), mit dem Punktoperator wir sind - für unsere eigene Bequemlichkeit -. Sofort abzieht, primitiver Wert des erzeugten Objekts

In der zweiten Zeile, wir nehmen den Wert in dem vorhergehenden Schritt erhalten, und den Vorteil der Tatsache, dass NaN ist nicht gleich alles im Universum, nicht einmal zu sich selbst, zum Beispiel: NaN == NaN >> false, um es schließlich zu vergleichen (für Ungleichheit) mit sich selbst

.

Auf diese Weise der Funktion Ertrag abwerfen wird true nur, wenn und nur dann, wenn die bereitgestellte Argument-Rückkehr, ist ein gescheiterter Versuch der Umwandlung in eine Anzahl Objekt, das heißt , eine not-a-number-Nummer; z.B. NaN.


isNaNstatic ()

Doch für einen statischen Typen Betreiber - bei Bedarf und bei Bedarf - können wir eine viel einfachere Funktion wie schreiben:

function isNaNstatic(x){   
   return x != x;
}

Und das DTC ganz zu vermeiden, so dass, wenn das Argument nicht explizit eine NaN Zahl ist, wird es false zurück. Darum Tests gegen die folgenden:

isNaNStatic(" x"); // will return false weil es ist immer noch ein String.

Allerdings: isNaNStatic(1/"x"); // will of course return true. als Wille zum Beispiel isNaNStatic(NaN); >> true.

Aber im Gegensatz zu isNaN, die isNaNStatic("NaN"); >> false, weil es (das Argument) ist ein gewöhnlicher String.

P. S .: Die statische Version von isNaN kann in moderner Codierung Szenarien sehr nützlich sein. Und es kann sehr wohl einer der Hauptgründe sein, ich meine Zeit für dieses Posting nahm.

Viele Grüße.

isNAN(<argument>) ist eine Funktion, zu sagen, ob gegebenes Argument ist illegal Zahl. isNaN Typumwandlungen, die Argumente in Zahlentyp. Wenn Sie möchten, zu überprüfen, ob Argument numerisch ist oder nicht? Bitte verwenden Sie $.isNumeric() Funktion in jQuery.

Das heißt, isNaN (foo) entspricht isNaN (Anzahl (foo)) Er akzeptiert keine Strings alle Zahlen als Zahlen aus offensichtlichen Gründen haben. Für ex.

isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false
isNaN('Hello') //true
isNaN('2005/12/12') //true
isNaN('') //false
isNaN(true) //false
isNaN(undefined) //true
isNaN('NaN') //true
isNaN(NaN) //true
isNaN(0 / 0) //true

Ich benutze diese

    function isNotANumeric(val) {
    	if(val.trim && val.trim() == "") {
         return true;
      } else {
      	 return isNaN(parseFloat(val * 1));
      }
    }
    
    alert(isNotANumeric("100"));  // false
    alert(isNotANumeric("1a"));   // true
    alert(isNotANumeric(""));     // true
    alert(isNotANumeric("   "));  // true

NaN! == "keine Zahl"

NaN ist ein Wert, der Nummer Typ

Dies ist eine Definition von isNaN () in ECMAScript

1. Let num be ToNumber(number).
2. ReturnIfAbrupt(num).
3. If num is NaN, return true.
4. Otherwise, return false.

Versuchen Sie einen beliebigen Wert Zahl zu konvertieren.

Number(" ") // 0
Number("x") // NaN
Number(null) // 0

Wenn Sie feststellen möchten, ob der Wert NaN ist, sollten Sie versuchen, es zu einem Zahlenwert zu konvertieren zunächst.

Bei der Prüfung, ob bestimmte Zeichenfolge-Wert mit Leerzeichen oder " "is isNaN versuchen vielleicht String-Validierung, darunter:

// value = "123 " if (value.match(/\s/) || isNaN(value)) { // do something }

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top