Konvertieren Sie NaN in Javascript in 0

238

Gibt es eine Möglichkeit, NaN-Werte ohne eine if-Anweisung in 0 umzuwandeln:

if (isNaN(a)) a = 0;

Es ist sehr ärgerlich, meine Variablen jedes Mal zu überprüfen.

Tamás Pap
quelle
4
Kannst du es nicht einfach in eine Funktion verwandeln?
the_drow
Dies ist nur wie 20 Zeichen, was ist das Problem?
Rusty Fausak
1
function noNaN( n ) { return isNaN( n ) ? 0 : n; }und dann geradenoNaN( a )
Šime Vidas
1
@rfausak Du willst dich im Allgemeinen nicht wiederholen (siehe TROCKEN ). Wenn eine bestimmte Funktionalität mehrmals benötigt wird, wird eine dedizierte Funktion bevorzugt.
Šime Vidas

Antworten:

574

Du kannst das:

a = a || 0

... die einen von einem beliebigen "Falsey" -Wert in umwandeln 0.

Die "Falsey" -Werte sind:

  • false
  • null
  • undefined
  • 0
  • "" ( leerer String )
  • NaN (Keine Nummer)

Oder wenn Sie es vorziehen:

a = a ? a : 0;

... was den gleichen Effekt wie oben hat.


Wenn Sie mehr als nur testen möchtenNaN , können Sie dasselbe tun, aber zuerst eine toNumber- Konvertierung durchführen.

a = +a || 0

Dies verwendet den unären + Operator, um zu versuchen, ain eine Zahl zu konvertieren . Dies hat den zusätzlichen Vorteil, dass beispielsweise numerische Zeichenfolgen '123'in eine Zahl konvertiert werden .

Das einzig Unerwartete kann sein, wenn jemand ein Array übergibt, das erfolgreich in eine Zahl konvertiert werden kann:

+['123']  // 123

Hier haben wir ein Array mit einem einzelnen Element, das eine numerische Zeichenfolge ist. Es wird erfolgreich in eine Zahl umgewandelt.

user113716
quelle
Die Idee, die Verifikation in eine Funktion umzuwandeln, ist gut, aber diese ist eleganter.
Tamás Pap
1
@ Bakudan: Guter Punkt. Ich dachte, OP befasse sich nur mit dem spezifischen NaNWert. Dies funktioniert nicht als Test für alle Nicht-Zahlenwerte. Obwohl wir zuerst eine toNumber-Konvertierung versuchen könnten. Ich werde aktualisieren.
user113716
... ah, es liegt am Titel "NaN in 0 konvertieren" . Wie auch immer, jetzt in beide Richtungen abgedeckt.
user113716
2
Danke Kumpel, habe dies für mich ein bisschen ausgewählt und modifiziert a = a * 1 || 0
Jemand
Genial. Vielen Dank
Apit John Ismail
32

Die Verwendung einer Doppel-Tilde (doppelt bitweise NICHT) - ~~- führt einige interessante Dinge in JavaScript aus. Zum Beispiel können Sie es anstelle von Math.flooroder sogar als Alternative zu verwenden parseInt("123", 10)! Es wurde viel über das Web diskutiert, daher werde ich nicht näher darauf eingehen, warum es hier funktioniert, aber wenn Sie interessiert sind: Was ist der Operator "double tilde" (~~) in JavaScript?

Wir können diese Eigenschaft einer Doppel-Tilde ausnutzen, um sie NaNin eine Zahl umzuwandeln , und glücklicherweise ist diese Zahl Null!

console.log(~~NaN); // 0

WickyNilliams
quelle
1
Danke, ich wusste überhaupt nichts davon ~~, ich habe es nur zusammen mit parseFloat()so benutzt : ~~parseFloat($variable);. Sehr ordentlich :) +1
Rens Tillmann
23

Schreiben Sie Ihre eigene Methode und verwenden Sie sie überall dort, wo Sie einen Zahlenwert wünschen:

function getNum(val) {
   if (isNaN(val)) {
     return 0;
   }
   return val;
}
Saket
quelle
1
Wenn ich passiere null, gibt es mir nicht das erwartete Ergebnis von 0. Mehr zu meinem Punkt hier: stackoverflow.com/questions/115548/why-is-isnannull-false-in-js
Andrei Bazanov
2
Nach meinem obigen Kommentar habe ich Number(val)stattdessen stattdessen verwendet, da es zurückkehrt, 0wenn es sowieso nicht herausgefunden werden kann.
Andrei Bazanov
4

Etwas Einfacheres und Effektiveres für alles:

function getNum(val) {
   val = +val || 0
   return val;
}

... die einen von einem beliebigen "Falsey" -Wert in umwandeln 0.

Die "Falsey" -Werte sind:

  • false
  • null
  • undefined
  • 0
  • "" ( leerer String )
  • NaN (Keine Nummer)
Woold
quelle
1
Interessant! Ich frage mich nur, wie es reagiert, wenn val ein negativer Wert sein kann. Soweit ich getestet habe, ist daran nichts auszusetzen, aber nur für den Fall ...
Luciano
2

Anstatt es zu kludgen, damit Sie fortfahren können, warum nicht sichern und sich fragen, warum Sie überhaupt auf ein NaN stoßen?

Wenn einer der numerischen Eingänge für eine Operation NaN ist, ist der Ausgang ebenfalls NaN. So funktioniert der aktuelle IEEE-Gleitkomma-Standard (nicht nur Javascript). Dieses Verhalten hat einen guten Grund : Die zugrunde liegende Absicht besteht darin, Sie davon abzuhalten, ein falsches Ergebnis zu verwenden, ohne zu bemerken, dass es falsch ist.

Die Art und Weise, wie NaN funktioniert, ist, wenn bei einer Sub-Sub-Sub-Operation (die ein NaN auf dieser niedrigeren Ebene erzeugt) etwas schief geht, das Endergebnis auch NaN ist, das Sie sofort als Fehler erkennen, selbst wenn Sie Die Fehlerbehandlungslogik (vielleicht werfen / fangen?) ist noch nicht vollständig.

NaN als Ergebnis einer arithmetischen Berechnung immer an, dass in den Details der Arithmetik etwas schief gelaufen ist. Auf diese Weise kann der Computer sagen, dass hier ein Debugging erforderlich ist. Anstatt einen Weg zu finden, mit einer Zahl fortzufahren, die kaum jemals richtig ist (ist 0 wirklich das, was Sie wollen?), Finden Sie das Problem und beheben Sie es.

Ein häufiges Problem in Javascript ist sowohl , dass parseInt(...)und parseFloat(...)wird NaN zurück , wenn ein unsinniges Argument angegeben ( null, ''usw.). Beheben Sie das Problem auf der niedrigstmöglichen Ebene und nicht auf einer höheren Ebene. Dann hat das Ergebnis der Gesamtberechnung gute Chancen, einen Sinn zu ergeben, und Sie ersetzen das Ergebnis der gesamten Berechnung nicht durch eine magische Zahl (0 oder 1 oder was auch immer). (Der Trick von (parseInt (foo.value) || 0) funktioniert nur für Summen, nicht für Produkte. Für Produkte soll der Standardwert 1 statt 0 sein, aber nicht, wenn der angegebene Wert wirklich 0 ist.)

Möglicherweise möchten Sie zur Vereinfachung der Codierung, dass eine Funktion einen Wert vom Benutzer abruft, bereinigt und bei Bedarf einen Standardwert bereitstellt, z. B.:

function getFoobarFromUser(elementid) {
        var foobar = parseFloat(document.getElementById(elementid).innerHTML)
        if (isNaN(foobar)) foobar = 3.21;       // default value
        return(foobar.toFixed(2));
}
Chuck Kollars
quelle
2

Wie wäre es mit einer Regex ?

function getNum(str) {
  return /[-+]?[0-9]*\.?[0-9]+/.test(str)?parseFloat(str):0;
}

Der folgende Code ignoriert NaN, um die Berechnung korrekt eingegebener Zahlen zu ermöglichen

mplungjan
quelle
2

Methoden, die isNaN verwenden, funktionieren nicht, wenn Sie versuchen, parseInt zu verwenden, zum Beispiel:

parseInt("abc"); // NaN
parseInt(""); // NaN
parseInt("14px"); // 14

Im zweiten Fall erzeugt isNaN jedoch false (dh die Nullzeichenfolge ist eine Zahl).

n="abc"; isNaN(n) ? 0 : parseInt(n); // 0
n=""; isNaN(n) ? 0: parseInt(n); // NaN
n="14px"; isNaN(n) ? 0 : parseInt(n); // 14

Zusammenfassend wird die Nullzeichenfolge von isNaN als gültige Zahl betrachtet, nicht jedoch von parseInt. Verifiziert mit Safari, Firefox und Chrome unter OSX Mojave.

David Crowe
quelle
1
Eine offensichtliche Lösung ist etwas umständlich. Suchen Sie nach parseInt nach NaN, nicht vorher: isNaN (parseInt (n))? parseInt (n): 0; // ruft parseInt zweimal auf :(
David Crowe
1
Dieser Kommentar sollte (der Anfang) Ihrer Antwort sein!
frandroid
Eine effizientere Lösung setzt voraus, dass die Nullzeichenfolge die einzige Anomalie ist: n == "" || isNaN (n)? 0: parseInt (n); (aber was ist, wenn es andere Saiten gibt?)
David Crowe
1
var i = [NaN, 1,2,3];

var j = i.map(i =>{ return isNaN(i) ? 0 : i});

console.log(j)

[0,1,2,3]

KARTHIKEYAN.A
quelle
0

Verwenden der Benutzerlösung 113716, die übrigens großartig ist, um all diese zu vermeiden, wenn ich sie auf diese Weise implementiert habe, um meine Zwischensummen-Textbox aus der Textbox-Einheit und der Textbox-Menge zu berechnen.

Beim Schreiben von Nicht-Zahlen in Textfelder für Einheiten und Mengen werden ihre Werte durch Null ersetzt, sodass die endgültige Buchung von Benutzerdaten keine Nicht-Zahlen enthält.

     <script src="/common/tools/jquery-1.10.2.js"></script>
     <script src="/common/tools/jquery-ui.js"></script>

     <!----------------- link above 2 lines to your jquery files ------>





    <script type="text/javascript" >
    function calculate_subtotal(){

    $('#quantity').val((+$('#quantity').val() || 0));
    $('#unit').val((+$('#unit').val() || 0));

    var  calculated = $('#quantity').val() * $('#unit').val() ;
    $('#subtotal').val(calculated);


    }
    </script>


      <input type = "text" onChange ="calculate_subtotal();" id = "quantity"/>
      <input type = "text" onChange ="calculate_subtotal();" id = "unit"/>
      <input type = "text" id = "subtotal"/>
webzy
quelle
0

Bitte versuchen Sie diese einfache Funktion

var NanValue = function (entry) {
    if(entry=="NaN") {
        return 0.00;
    } else {
        return entry;
    }
}
subindas pm
quelle