Validierung von Dezimalzahlen in JavaScript: Warum IsNumeric() den Code zerstört und wie man es behebt
\n\nJeder Entwickler, der auch nur eine Woche in JavaScript programmiert hat, steht früher oder später vor der Aufgabe: „Prüfen, ob ein String eine Zahl ist.“ Was könnte einfacher sein? Die eingebaute Funktion isNaN() oder parseFloat() – und schon ist die Sache erledigt. Aber weit gefehlt. Die Frage „Validate decimal numbers in JavaScript — IsNumeric()“ auf Stack Overflow hat Hunderttausende von Aufrufen und Dutzende widersprüchliche Antworten gesammelt. Warum? Weil JavaScript eine Sprache ist, in der typeof NaN === 'number' ist und ein leerer String als Null betrachtet wird.
In diesem Artikel geben wir nicht einfach eine fertige isNumeric()-Funktion. Wir analysieren die 5 häufigsten und gefährlichsten Fehler, die selbst erfahrene Programmierer machen, und zeigen, wie man sie vermeidet. Sie erfahren, warum isNaN eine Falle ist, wie die Typumwandlung funktioniert und welche Methode zur Zahlenvalidierung in JS wirklich in der Produktion eingesetzt werden sollte.
Warum isNaN() böse ist (und wann es funktioniert)
\n\nBeginnen wir mit dem Offensichtlichen. Viele Anfänger schreiben so:
\n\nfunction isNumeric(n) {\n return !isNaN(n);\n}\n\n\nAuf den ersten Blick logisch: Wenn nicht NaN, dann Zahl. Aber testen wir es:
\n\nconsole.log(isNumeric('123')); // true — ok\nconsole.log(isNumeric('12.3')); // true — ok\nconsole.log(isNumeric('')); // true — HOPPLA! Leerer String ist eine Zahl?\nconsole.log(isNumeric(' ')); // true — Leerzeichen auch eine Zahl?\nconsole.log(isNumeric(null)); // true — null ist eine Zahl?\nconsole.log(isNumeric(true)); // true — true ist 1\n\n\nFehler Nr. 1: isNaN() wandelt das Argument zuerst in eine Zahl um und prüft dann. Der leere String '' wird zu 0, null zu 0, true zu 1. Infolgedessen betrachtet die Funktion Dinge als Zahlen, die keine Zahlen sind.
Es gibt eine strikte Variante – Number.isNaN() (ES6), aber diese prüft nur, ob der Wert genau NaN ist, ohne Umwandlung. Für die Zahlenvalidierung taugt sie auch nicht.
parseFloat: Held oder Schurke?
\n\nDer zweite beliebte Ansatz ist die Verwendung von parseFloat():
function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n}\n\n\nDiese Variante ist schon besser, hat aber ein anderes Problem:
\n\nconsole.log(isNumeric('123abc')); // true — parseFloat beißt '123' ab, ignoriert 'abc'\nconsole.log(isNumeric('12.3.4')); // true — den zweiten Punkt bemerkt parseFloat einfach nicht\nconsole.log(isNumeric('Infinity')); // true — Unendlichkeit ist eine Zahl?\n\n\nFehler Nr. 2: parseFloat() parst den String bis zum ersten ungültigen Zeichen. Der String '123abc' ist für ihn 123. Aber der Benutzer könnte versehentlich eine zusätzliche Taste gedrückt haben, und wir müssen das abfangen.
Fehler Nr. 3: isFinite() schließt Infinity und -Infinity aus, lässt aber NaN und undefined durch. Das Problem ist, dass isFinite(null) true zurückgibt, weil null in 0 umgewandelt wird.
Fehler Nr. 4: Reguläre Ausdrücke – Allheilmittel oder neue Hölle?
\n\nWenn Entwickler verstehen, dass die eingebauten Funktionen unzuverlässig sind, verfallen sie oft ins andere Extrem – reguläre Ausdrücke. Und dann beginnt das wahre Chaos.
\n\nHier ist ein typischer, aber gefährlicher Regex:
\n\nfunction isNumeric(n) {\n return /^\\d+$/.test(n);\n}\n\n\nProbleme:
\n- \n
- Lässt keine Dezimalpunkte zu (
'12.3'— false) \n - Lässt keine negativen Zahlen zu (
'-5'— false) \n - Lässt keine wissenschaftliche Notation zu (
'1e5'— false) \n
Hier ist eine „ver