Mathematische Operatoren und das „Math“-Objekt
Funktionen
Ausblick auf das DOM (Teil 1 von 2)

JavaScript: Arbeiten mit NaN (= Not a Number) und dem NaN-Paradoxon

Was ist NaN?

NaN steht für „Not a Number“ – auf Deutsch: „Keine Zahl“. Interessanterweise ist NaN selbst als Zahlenwert in JavaScript definiert. Dieser scheinbare Widerspruch ist der Kern des sogenannten NaN-Paradoxons. NaN ist ein besonderer Wert, der auftritt, wenn eine mathematische Operation keinen sinnvollen Zahlenwert liefern kann.

Die Entstehung von NaN

NaN entsteht in verschiedenen Situationen. Hier die häufigsten:

1. Ungültige mathematische Operationen

let ergebnis = 0 / 0;
console.log(ergebnis); // NaN

let wurzel = Math.sqrt(-1);
console.log(wurzel); // NaN (keine reelle Quadratwurzel aus negativen Zahlen)

2. Fehlgeschlagene Typumwandlungen

let zahl = Number("Hallo");
console.log(zahl); // NaN

let berechnung = 5 * "Welt";
console.log(berechnung); // NaN

3. Operationen mit NaN

let x = NaN;
let ergebnis = x + 5;
console.log(ergebnis); // NaN (NaN infiziert andere Berechnungen)

Die Eigenheiten von NaN

Paradox 1: NaN ist vom Typ Number

Der erste Teil des Paradoxons: NaN ist selbst vom Typ „Number“, obwohl es „Not a Number“ bedeutet.

console.log(typeof NaN); // "number"

Dieser Widerspruch entsteht, weil NaN ein spezieller Wert innerhalb des IEEE 754 Fließkommazahlen-Standards ist. Es repräsentiert einen undefinierten oder nicht darstellbaren Zahlenwert.

Paradox 2: NaN ist mit nichts gleich – nicht einmal mit sich selbst

Das zweite Teil des Paradoxons und wohl die merkwürdigste Eigenschaft: NaN ist der einzige Wert in JavaScript, der nicht mit sich selbst identisch ist.

console.log(NaN === NaN); // false
console.log(NaN == NaN); // false

// Selbst diese Vergleiche funktionieren nicht
console.log(NaN !== NaN); // true (NaN ist nicht gleich NaN!)

Paradox 3: Die einzige wahre Ungleichheit

NaN ist der einzige Wert, für den gleichzeitig gilt:

  • x === x ist false
  • x !== x ist true
let x = NaN;
console.log(x === x); // false
console.log(x !== x); // true

Für alle anderen Werte in JavaScript ist die erste Aussage immer wahr und die zweite immer falsch.

Paradox 4: Vergleiche mit NaN ergeben immer false

Jeder Vergleich mit NaN ergibt false – selbst wenn man explizit auf Ungleichheit prüft:

console.log(NaN < 1);  // false
console.log(NaN > 1); // false
console.log(NaN <= 1); // false
console.log(NaN >= 1); // false

Wie erkennt man NaN?

Da NaN nicht mit sich selbst verglichen werden kann, brauchst du spezielle Methoden, um es zu erkennen.

Die isNaN()-Funktion

Die globale isNaN()-Funktion prüft, ob ein Wert NaN ist. Achtung: Sie versucht zuerst, den Wert in eine Zahl umzuwandeln.

console.log(isNaN(NaN));       // true
console.log(isNaN(undefined)); // true (weil undefined zu NaN konvertiert wird)
console.log(isNaN("Hallo")); // true (weil "Hallo" nicht zu einer Zahl konvertiert werden kann)
console.log(isNaN("123")); // false (weil "123" zu einer Zahl konvertiert werden kann)
console.log(isNaN(true)); // false (weil true zu 1 konvertiert wird)

Die Number.isNaN()-Methode

Die neuere Number.isNaN()-Methode ist präziser. Sie prüft, ob ein Wert tatsächlich NaN ist, ohne vorherige Typumwandlung.

console.log(Number.isNaN(NaN));       // true
console.log(Number.isNaN(undefined)); // false (undefined ist nicht NaN)
console.log(Number.isNaN("Hallo")); // false (ein String ist nicht NaN)

Der selbst-ungleich Trick

Eine interessante Methode, NaN zu erkennen, nutzt die Eigenschaft, dass es nicht mit sich selbst übereinstimmt:

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

console.log(istNaN(NaN)); // true
console.log(istNaN(123)); // false
console.log(istNaN("Hallo")); // false

Dieser Trick funktioniert, weil NaN der einzige Wert ist, der diese Eigenschaft besitzt.

Praktische Auswirkungen des NaN-Paradoxons

Das NaN-Paradoxon kann zu schwer auffindbaren Fehlern führen. Hier einige typische Problemfälle und Lösungen:

Problem 1: Fortpflanzung von NaN in Berechnungen

NaN „infiziert“ weitere Berechnungen:

let eingabe = Number("nicht numerisch");
let summe = 0;

// NaN breitet sich in allen weiteren Berechnungen aus
for (let i = 0; i < 10; i++) {
summe += eingabe;
}

console.log(summe); // NaN, die gesamte Berechnung ist betroffen

Problem 2: Irreführende Vergleiche

let alter = Number(prompt("Wie alt bist du?"));

// Falls der Benutzer "zwanzig" eingibt
if (alter < 18) {
console.log("Du bist minderjährig");
} else {
console.log("Du bist volljährig");
}
// Keiner der Zweige wird ausgeführt, da NaN < 18 false ist und NaN >= 18 auch false ist!

Lösung: NaN immer prüfen und behandeln

let eingabe = prompt("Gib dein Alter ein:");
let alter = Number(eingabe);

if (Number.isNaN(alter)) {
console.log("Das ist keine gültige Zahl!");
} else if (alter < 18) {
console.log("Du bist minderjährig");
} else {
console.log("Du bist volljährig");
}

Arrays und NaN

Das NaN-Paradoxon zeigt sich auch bei der Arbeit mit Arrays:

let zahlen = [1, 2, NaN, 3];

// indexOf findet NaN nicht
console.log(zahlen.indexOf(NaN)); // -1

// includes findet NaN tatsächlich!
console.log(zahlen.includes(NaN)); // true

// filter mit direktem Vergleich funktioniert nicht
console.log(zahlen.filter(zahl => zahl === NaN)); // []

// filter mit Number.isNaN funktioniert
console.log(zahlen.filter(zahl => Number.isNaN(zahl))); // [NaN]

NaN in modernem JavaScript

In modernem JavaScript gibt es einige Wege, besser mit NaN umzugehen:

1. Optional Chaining und Nullish Coalescing

// Verhindere NaN durch Standardwerte
let eingabe = Number(benutzerEingabe || "0");

// Oder besser mit Nullish Coalescing (??), das nur bei null/undefined einspringt
let sichereEingabe = Number(benutzerEingabe ?? "0");

2. Destructuring mit Standardwerten

// Extrahiere Zahlen aus Objekten mit Standardwerten
const { alter = 0 } = benutzer;

3. Array-Methoden zum Umgang mit NaN

const zahlen = [1, 2, NaN, 3, NaN];

// Entferne alle NaN-Werte
const bereinigteMenge = zahlen.filter(zahl => !Number.isNaN(zahl));
console.log(bereinigteMenge); // [1, 2, 3]

Praktische Tipps zum Umgang mit NaN

  1. Eingaben immer prüfen: Validiere Benutzereingaben, bevor du sie in Zahlen umwandelst.
function istGültigeZahl(eingabe) {
return !isNaN(parseFloat(eingabe)) && isFinite(eingabe);
}
  1. Default-Werte verwenden: Setze vernünftige Standardwerte, falls NaN auftritt.
let alter = Number(eingabe);
if (Number.isNaN(alter)) {
alter = 0; // Standardwert
}
  1. Früh scheitern: Prüfe auf NaN am Anfang einer Funktion und gib früh einen Fehler zurück.
function berechneRabatt(preis, prozentsatz) {
if (Number.isNaN(preis) || Number.isNaN(prozentsatz)) {
throw new Error("Ungültige Zahlen für die Rabattberechnung");
}
return preis * (prozentsatz / 100);
}
  1. Verwende spezialisierte Hilfsfunktionen: Erstelle Funktionen, die NaN-Werte erkennen und behandeln.
function sichereAddition(a, b) {
if (Number.isNaN(a) || Number.isNaN(b)) {
return 0; // oder einen anderen Standardwert
}
return a + b;
}

Zusammenfassung

Das NaN-Paradoxon in JavaScript beschreibt mehrere merkwürdige Eigenschaften eines speziellen Zahlenwerts:

  1. NaN ist ein Zahlenwert, der „Keine Zahl“ bedeutet.
  2. NaN ist nicht gleich sich selbst.
  3. NaN infiziert alle nachfolgenden Berechnungen.
  4. NaN erfordert spezielle Erkennungsmethoden.

Diese Eigenheiten machen NaN zu einem wichtigen Konzept, das du verstehen musst, um robuste JavaScript-Programme zu schreiben. Mit den richtigen Techniken kannst du das NaN-Paradoxon meistern und damit verbundene Probleme vermeiden.