Wie verwandle ich NaN von parseInt in 0 für eine leere Zeichenfolge?

298

Ist es möglich, 0 zurückzugeben, anstatt NaNWerte in JavaScript zu analysieren?

Im Falle der leeren Zeichenfolge wird parseIntzurückgegeben NaN.

Ist es möglich, so etwas in JavaScript zu überprüfen NaN?

var value = parseInt(tbb) == NaN ? 0 : parseInt(tbb)

Oder gibt es vielleicht eine andere Funktion oder ein anderes jQuery-Plugin, das etwas Ähnliches tun kann?

Joper
quelle
72
Zu Ihrer Information , NaN != NaN. Du würdest brauchen isNaN(value).
Pimvdb
28
Ja, keine zwei Kindermädchen sind gleich;)
James P.
3
Ein parseInt()zweimaliger Aufruf der Funktion (im erfolgreichen / normalen NaNFall) ist niemals eine gute Idee. Abgesehen von Ineffizienz ist es für Unvorsichtige tbbschrecklich, wenn ein Funktionsaufruf mit Nebenwirkungen übergeben wird. Ich würde hier keine Lösung verwenden, wo ich parseInt()zweimal sehe .
JonBrave

Antworten:

756
var s = '';

var num = parseInt(s) || 0;

Wenn der ||Operator logisch ODER ( ) nicht mit booleschen Werten verwendet wird, gibt er den ersten Ausdruck ( parseInt(s)) zurück, wenn er als wahr ausgewertet werden kann, andernfalls gibt er den zweiten Ausdruck (0) zurück. Der Rückgabewert von parseInt('')ist NaN. NaN wird als falsch ausgewertet und numam Ende auf 0 gesetzt.

Matthew
quelle
6
Dies funktioniert nicht, wenn s = "4s"; (es gibt 4 zurück ... was falsch ist ...)
markzzz
1
parseInt Funktion in js parse alle Zahlen in Zeichenfolge
ali youhannaei
26
@markzzz Frage noch einmal lesen. OP fragt: " Ist es irgendwie möglich, 0 anstelle von NaN zurückzugeben? " OP möchte nicht überprüfen, ob eine bestimmte Zeichenfolge für int analysiert werden kann. OP will 0statt bekommen NaN. Dies wird durch Matts Code perfekt gelöst.
Trejder
2
@markzzzvar nextIphone = parseInt("4S") + 1; // wow it works!
Zero Distraction
2
@ Matthew bitte verwenden Sie die Begriffe "falsch" oder "wahr" . weil NaN === falsch ist falsch! aber Boolean (NaN) === Boolean (false) ist wahr. Das logische ODER gibt den ersten Ausdruck zurück, wenn er als "wahr"
Pablo Recalde
52

Sie können auch die isNaN()Funktion verwenden:

var s = ''
var num = isNaN(parseInt(s)) ? 0 : parseInt(s)
gprasant
quelle
12
Warum parseInt(s)zweimal anrufen ? Außerdem sollte es seinparseInt(s, 10)
Dexygen
2
@GeorgeJempty Ein Radix von "10" ist die Standardeinstellung. Dieser Parameter ist optional. Guter Punkt, parseInt()wenn Sie zweimal anrufen .
Herbst Leonard
8
@AutumnLeonard das ist nur irgendwie wahr. Wenn Ihre Zeichenfolge mit einer 0 beginnt, wird davon ausgegangen, dass die Zahl im Oktalformat vorliegt, sodass parseInt ('077') 63 ergibt. Dies kann zu sehr unangenehmen Fehlern führen. Daher sollten Sie immer den zweiten Parameter angeben. siehe zum Beispiel stackoverflow.com/questions/8763396/…
chuck258
22

Ich war überrascht, dass niemand die Verwendung erwähnte Number(). Zugegeben, es analysiert Dezimalstellen, wenn dies vorgesehen ist, verhält sich also anders als parseInt(), nimmt jedoch bereits die Basis 10 an und wandelt "" oder sogar "" in 0 um.

Chris Werner
quelle
1
Ja, sehr praktisch zum Lesen von localStorage: Number (localStorage.getItem ('appBanner.count')) + 1
Philip Murphy
Während dies für die gestellte Frage funktioniert, gibt es immer noch NaN für Nicht-Zahlen-Nicht-Leerzeichen zurück
Kyle Delaney,
9

Für Personen, die nicht darauf beschränkt sind parseInt, können Sie den bitweisen ODER-Operator verwenden (der implizit ToInt32seine Operanden aufruft ).

var value = s | 0;

// NaN | 0     ==>> 0
// ''  | 0     ==>> 0
// '5' | 0     ==>> 5
// '33Ab' | 0  ==>> 0
// '0x23' | 0  ==>> 35
// 113 | 0     ==>> 113
// -12 | 0     ==>> -12
// 3.9 | 0     ==>> 3

Hinweis: ToInt32unterscheidet sich von parseInt. (dh parseInt('33Ab') === 33)

Ahmad Ibrahim
quelle
Aber : '10000000000' | 0 === 1410065408.
Trincot
@trincot ja, jeder Wert> = Math.pow(2, 31)läuft über.
Ahmad Ibrahim
8

Das Problem

Andere Antworten berücksichtigen nicht, dass dies 0falsch ist, und daher lautet das Folgende 20 anstelle von 0:

const myNumber = parseInt('0') || 20; // 20

Die Lösung

Ich schlage eine Hilfsfunktion vor, die die meisten Probleme löst:

function getNumber({ value, defaultValue }) {
  const num = parseInt(value, 10);
  return isNaN(num) ? defaultValue : num;
}

Die Hilfsfunktion liefert folgende Ergebnisse:

getNumber({ value: "0", defaultValue: 20 }); // 0
getNumber({ value: "2", defaultValue: 20 }); // 2
getNumber({ value: "2.2", defaultValue: 20 }); // 2
getNumber({ value: "any string", defaultValue: 20 }); // 20
getNumber({ value: undefined, defaultValue: 20 }); // 20
getNumber({ value: null, defaultValue: 20 }); // 20
getNumber({ value: NaN, defaultValue: 20 }); // 20
getNumber({ value: false, defaultValue: 20 }); // 20
getNumber({ value: true, defaultValue: 20 }); // 20
sqren
quelle
2
Bitte geben Sie eine Radix zu ParseInt senden: parseInt(string, radix), bedenken Sie: parseInt("0x10") === 16Auch parseInt("010")ergeben könnte 8in einigen Browsern
andlrc
2
Wenn Sie für andere Dinge bereits auf lodash angewiesen sind, gibt es eine praktische defaultToFunktion, die genau dies tut: _.defaultTo(NaN, -1)return -1, aber _.defaultTo(0, -1);return 0.
Waldyrious
Dies ist ein ausgezeichneter Punkt! Sie können sich nur auf das || verlassen am Ende, um den korrekten Standardwert anzugeben, wenn Ihr bevorzugter Standardwert NULL ist (zugegeben, dies ist das, was das OP wollte). Wie Sie bereits erwähnt haben, wird die Eingabe '0' in diesem Fall aufgrund der falschen Natur als ungültige Eingabe behandelt, und die Anweisung gibt stattdessen den Standardwert zurück (möglicherweise nicht das, was erwartet wurde!)
JonathanDavidArndt,
Sicherlich sollten Sie eine Konstante verwenden, anstatt parseIntzweimal
Kyle Delaney,
4

Ist der Job meiner Meinung nach viel sauberer als parseInt? Verwenden Sie den Operator +

var s = '';
console.log(+s);

var s = '1024'
+s
1024

s = 0
+s
0

s = -1
+s
-1

s = 2.456
+s
2.456

s = ''
+s
0

s = 'wtf'
+s
NaN
PirateApp
quelle
1
Sehr kompakt. Was für eine Schande, dass Sie nicht mehr Punkte bekommen haben. Ich habe dich gewählt. Bitte erwidern Sie dies, um zu versuchen, meine heute von einem stummen Troll erworbenen -2 zu fangen ... (siehe meine Antwort am Ende dieser Seite). Danke dir.
Fabien Haddadi
2
var value = isNaN(parseInt(tbb)) ? 0 : parseInt(tbb);
Milap Jethwa
quelle
1

Führen Sie eine separate Prüfung für eine leere Zeichenfolge durch (da es sich um einen bestimmten Fall handelt) und setzen Sie sie in diesem Fall auf Null.

Sie könnten am Anfang "0" eingeben, aber dann müssen Sie ein Präfix hinzufügen, um anzuzeigen, dass es sich um eine Dezimalzahl und nicht um eine Oktalzahl handelt

Schröder Cat
quelle
Sie denken also, es ist besser, 0 anzuhängen, wenn leer?
Joper
1
Nein - das ist ein Ansatz, den ich verwendet habe. In diesem Fall wäre eine separate Prüfung besser. Wenn die Matts-Lösung jedoch funktioniert, ist sie noch sauberer.
Schroedingers Cat
1

Warum nicht die Funktion überschreiben? In diesem Fall können Sie immer sicher sein, dass es zurückkehrt, 0wenn NaN:

(function(original) {
    parseInt = function() {
        return original.apply(window, arguments) || 0;
    };
})(parseInt);

Jetzt überall in Ihrem Code:

parseInt('') === 0
pimvdb
quelle
15
Das Überschreiben dieser Funktion könnte erfahrene JavaScript-Programmierer verwirren, die dies möglicherweise als Fehler ansehen. Ihre überschriebene Funktion wird wahrscheinlich irgendwo vergraben, wo sie wahrscheinlich nicht gesehen wird. Das ist kreativ, aber ich bin mir nicht sicher, ob ich es persönlich empfehlen würde, wenn man bedenkt, wie einfach es ist, einfach ein || 0wie in Matts Antwort hinzuzufügen . Ich sehe das Überschreiben von Objekten, die Sie nicht besitzen, als letzten Ausweg oder wenn Sie dies nicht tun, würde dies erheblich mehr Zeit und Komplexität kosten.
jmort253
2
Ich stimme @ jmort253 zu ... Es ist gefährlich, weil die Funktion zu intelligent ist. Es ist besser, genau die gleiche Funktion auszuführen, jedoch mit einem Namen wie getSafeNumberValue oder ähnlichem.
Samuel
1

Ich hatte ein ähnliches Problem (Firefox v34) mit einfachen Zeichenfolgen wie:

var myInt = parseInt("b4");

Also kam ich auf einen kurzen Hack von:

var intVal = ("" + val).replace(/[^0-9]/gi, "");

Und dann wurde alles dumm kompliziert, mit Floats + Ints für nicht einfache Sachen umzugehen:

var myval = "12.34";

function slowParseNumber(val, asInt){
    var ret = Number( ("" + val).replace(/[^0-9\.]/gi, "") );
    return asInt ? Math.floor(ret) : ret;
}
var floatVal = slowParseNumber(myval);

var intVal = slowParseNumber(myval, true);
console.log(floatVal, intVal);

Es wird 0 zurückgeben für Dinge wie:

var intVal = slowParseNumber("b"); // yeilds 0
Bob
quelle
1
//////////////////////////////////////////////////////
function ToInt(x){x=parseInt(x);return isNaN(x)?0:x;}
//////////////////////////////////////////////////////
var x = ToInt('');   //->  x=0
    x = ToInt('abc') //->  x=0
    x = ToInt('0.1') //->  x=0
    x = ToInt('5.9') //->  x=5
    x = ToInt(5.9)   //->  x=5
    x = ToInt(5)     //->  x=5
AbdulRahman AlShamiri
quelle
Können Sie diese Lösung erklären?
RamenChef
Wenn Sie eine beliebige Zahl (wie '123' oder 123) in eine Ganzzahl umwandeln möchten, wenn Sie parseInt ('abc') verwenden,
AbdulRahman AlShamiri
Wenn Sie parseInt ('abc') verwenden, gelangen Sie zu NaN, aber diese Funktion konvertiert das NaN in 0
AbdulRahman AlShamiri
Bingo als explizite Alternative zum ||Ansatz. Ich weiß, dass dies eine alte Frage und Antwort ist, aber diese Antwort vermeidet es, parseInt zweimal aufzurufen, und verwendet isNaN korrekt. Es braucht nur den Radix parseInt(x, 10), um gründlich zu sein. (Meine Präferenz ist eine separate interne Variable anstatt x
wiederzuverwenden
1

Ich habe einen 2-Prototyp erstellt, um dies für mich zu erledigen, einen für eine Zahl und einen für einen String.

// This is a safety check to make sure the prototype is not already defined.
Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
        return this;
    }
};

// returns the int value or -1 by default if it fails
Number.method('tryParseInt', function (defaultValue) {
    return parseInt(this) == this ? parseInt(this) : (defaultValue === undefined ? -1 : defaultValue);
});

// returns the int value or -1 by default if it fails
String.method('tryParseInt', function (defaultValue) {
    return parseInt(this) == this ? parseInt(this) : (defaultValue === undefined ? -1 : defaultValue);
});

Wenn Sie den Sicherheitscheck nicht verwenden möchten, verwenden Sie

String.prototype.tryParseInt = function(){
    /*Method body here*/
};
Number.prototype.tryParseInt = function(){
     /*Method body here*/
};

Anwendungsbeispiel:

var test = 1;
console.log(test.tryParseInt()); // returns 1

var test2 = '1';
console.log(test2.tryParseInt()); // returns 1

var test3 = '1a';
console.log(test3.tryParseInt()); // returns -1 as that is the default

var test4 = '1a';
console.log(test4.tryParseInt(0));// returns 0, the specified default value
Mike
quelle
1
// implicit cast
var value = parseInt(tbb*1); // see original question

Erklärung für diejenigen, die es nicht trivial finden:

Durch Multiplizieren mit eins, einer Methode namens "implizite Umwandlung", wird versucht, den Operanden vom unbekannten Typ in den primitiven Typ 'number' umzuwandeln. Insbesondere würde eine leere Zeichenfolge die Nummer 0 werden, was sie zu einem geeigneten Typ für parseInt () ... macht.

Ein sehr gutes Beispiel wurde oben auch von PirateApp gegeben, der vorschlug, das + -Zeichen voranzustellen, wodurch JavaScript gezwungen wurde, die implizite Umwandlung von Number zu verwenden.

Fabien Haddadi
quelle
Es ist eine direkte Antwort auf die ursprüngliche Frage, meine Liebe.
Fabien Haddadi
Dies reicht nicht fürparseInt('str'*1)
Rodion Baskakov
Warum parseIntetwas anrufen , das bereits eine Nummer ist? Dies führt zu einer weiteren Konvertierung zurück in einen String, um diese erneut in eine Nummer zu konvertieren.
Trincot
0

Schreiben Sie auch auf diese Weise eine Funktion und rufen Sie sie auf, wo immer dies erforderlich ist. Ich gehe davon aus, dass dies der Eintrag in die Formularfelder ist, um Berechnungen durchzuführen.

var Nanprocessor = function (entry) {
    if(entry=="NaN") {
        return 0;
    } else {
        return entry;
    }
}

 outputfield.value = Nanprocessor(x); 

// where x is a value that is collected from a from field
// i.e say x =parseInt(formfield1.value); 

Was ist falsch daran?

Naresh
quelle
Hallo, was hindert uns daran, der obigen Methode zu folgen. Würde gerne wissen und lernen.
Naresh
3
Sie sollten isNaN zum Testen verwenden NaN.
Matthew
2
Danke Matt :) Ich weiß nicht, dass es in javascrip eine Funktion namens isNaN () gibt! Danke für die Information...!
Naresh
0

Hier ist eine tryParseInt-Methode, die ich verwende. Dabei wird der Standardwert als zweiter Parameter verwendet, sodass alles sein kann, was Sie benötigen.

function tryParseInt(str, defaultValue) {
    return parseInt(str) == str ? parseInt(str) : defaultValue;
}

tryParseInt("", 0);//0 
tryParseInt("string", 0);//0 
tryParseInt("558", 0);//558
Darrelk
quelle
0

eine Hilfsfunktion, mit der der Radix weiterhin verwendet werden kann

function parseIntWithFallback(s, fallback, radix) {
    var parsed = parseInt(s, radix);
    return isNaN(parsed) ? fallback : parsed;
}
Jerome Diaz
quelle
0

Sie können sehr sauberen Code haben, ich hatte ähnliche Probleme und ich löste es mit:

var a="bcd";
~~parseInt(a);
Bishal Gautam
quelle
0

Für andere Leute, die nach dieser Lösung suchen, verwenden Sie einfach: ~~ ohne parseInt, es ist der sauberste Modus.

var a = 'hello';
var b = ~~a;

Wenn NaN, wird stattdessen 0 zurückgegeben.

OBS. Diese Lösung gilt nur für ganze Zahlen

Marcos Mendes
quelle