mitmario.dev

Typen umwandeln

JavaScript Im Browser 3 Min Lesezeit 4 BeispieleLektion 7 von 9

Werte wechseln in JavaScript ständig den Typ. Manchmal, weil du es willst, und manchmal, weil die Sprache es hinter deinem Rücken tut. Das zweite ist die Ursache der meisten unerklärlichen Ergebnisse, und deshalb steht diese Lektion vor Abschnitt 3.

Absichtlich umwandeln

Absichtlich umwandeln
// Text zu Zahl.
console.log(Number("42"), typeof Number("42"));
console.log(Number("19.99"), typeof Number("19.99"));

// Zahl zu Text.
console.log(String(42), typeof String(42));

// Irgendetwas zu einem Wahrheitswert.
console.log(Boolean("Hallo"), Boolean(""), Boolean(0), Boolean(1));

Drei Funktionen, benannt nach dem Ziel:

Number(wert) macht eine Zahl daraus. String(wert) macht Text daraus. Boolean(wert) macht einen Wahrheitswert daraus.

String brauchst du selten, weil Template Literals das schon erledigen. Boolean sieht man auch nicht oft, denn ein if wandelt von selbst um, und welcher Wert dabei als wahr gilt, ist Lektion 3.3.

Bleibt Number, und das brauchst du ständig, sobald Eingaben ins Spiel kommen.

Number gegen parseInt

Number gegen parseInt
// Number will den ganzen Text als Zahl lesen. Klappt das nicht, gibt es NaN.
console.log("Number:", Number("12px"));

// parseInt liest von vorn, so weit es geht, und hört dann auf.
console.log("parseInt:", parseInt("12px", 10));

// Für Kommazahlen gibt es parseFloat.
console.log("parseFloat:", parseFloat("19.99 Euro"));

// Steht vorn keine Ziffer, hilft auch parseInt nicht.
console.log("Von vorn kaputt:", parseInt("px12", 10));

Die beiden sehen ähnlich aus und verhalten sich verschieden.

Number will den ganzen Text als Zahl lesen. Steht irgendwo ein Zeichen, das nicht dazugehört, ist das Ergebnis NaN. Number("12px") ist also NaN.

parseInt liest von vorn und hört auf, sobald es nicht mehr weitergeht. parseInt("12px", 10) ist 12. Für Kommazahlen gibt es parseFloat, das zusätzlich den Punkt mitliest.

Beide brechen ab, wenn schon vorn keine Ziffer steht: parseInt("px12", 10) ist wieder NaN.

Die zweite Zahl bei parseInt heißt Basis und sagt: lies das im Zehnersystem. Ohne sie funktioniert es meistens auch, aber eben nur meistens, und die Ausnahmen betreffen Texte mit führender Null. Schreib die 10 einfach immer hin, sie kostet nichts.

Welches nimmt man wann? Number ist die strengere und damit die bessere Voreinstellung. Wenn jemand 12px in ein Feld tippt, in das eine Anzahl gehört, willst du das meistens als Fehler behandeln und nicht heimlich als 12 lesen. parseInt nimmst du dort, wo eine Einheit erwartungsgemäß dranhängt, etwa beim Auslesen von CSS-Werten in Abschnitt 11.

Die stille Umwandlung

Jetzt der Teil, der wehtut.

Die stille Umwandlung beim Plus
// Ein Plus mit einem Text auf einer Seite verbindet, statt zu rechnen.
console.log("5" + 1);

// Minus, mal und geteilt kennen das Verbinden nicht. Sie rechnen immer
// und wandeln den Text vorher stillschweigend um.
console.log("5" - 1);
console.log("5" * 2);
console.log("10" / 2);

// Deshalb ist ausgerechnet das Plus der Operator, bei dem du aufpassen musst.
console.log(typeof ("5" + 1), typeof ("5" - 1));

"5" + 1 ergibt "51". "5" - 1 ergibt 4.

Tipp die beiden Zeilen in die Eingabezeile der Console, dann siehst du mehr als die Werte. Auf die erste antwortet sie mit "51" in Anführungszeichen, auf die zweite mit 4 ohne. Die Zeichen sind kein Schmuck: Sie sagen dir, dass das eine ein Text ist und das andere eine Zahl. Genau diese Auskunft fehlt dir in der Ausgabe deines eigenen Programms, denn console.log("51") und console.log(51) schreiben beide dieselbe Zeile.

Der Grund ist, dass das Plus zwei Bedeutungen hat. Es addiert Zahlen, und es verbindet Texte. Steht auf einer der beiden Seiten ein Text, entscheidet sich JavaScript fürs Verbinden und macht aus der Zahl ebenfalls Text.

Minus, mal und geteilt haben diese zweite Bedeutung nicht. Es gibt kein „Texte subtrahieren”, also bleibt nur eine Möglichkeit: Sie machen aus dem Text eine Zahl und rechnen. Deshalb funktioniert "5" - 1 klaglos.

Das ist bemerkenswert unlogisch, und du musst es trotzdem wissen, denn genau so verhält sich die Sprache. Merk dir: Beim Plus musst du aufpassen, bei den anderen dreien nicht.

Wo dich das trifft

Was aus einer Eingabe kommt
// So sieht der Wert aus, den ein Eingabefeld liefert: immer Text.
const eingabeMenge = "5";
const eingabePreis = "7";

// Ohne Umwandlung kommt Unsinn heraus.
console.log("Falsch:", eingabeMenge + eingabePreis);

// Mit Umwandlung stimmt es.
console.log("Richtig:", Number(eingabeMenge) + Number(eingabePreis));

Nicht in einer Übungsaufgabe, sondern beim ersten echten Formular.

Ein Eingabefeld liefert immer Text. Auch wenn type="number" daransteht, auch wenn der Nutzer eine Zahl eingetippt hat, auch wenn das Feld Pfeiltasten zum Hochzählen hat. Was du bekommst, ist die Zeichenfolge "5".

Addierst du zwei solche Werte, bekommst du "57" statt 12. Das ist der Bug, den man einmal im Leben baut. Und er ist unangenehm, weil die Zahl auf den ersten Blick plausibel aussieht: Aus 5 und 7 wird 57, und irgendwo im Kopf denkt man an einen Rechenfehler statt an einen Typfehler.

Die Gegenmaßnahme ist eine Gewohnheit: Wandle an der Grenze um. Alles, was von außen hereinkommt, machst du sofort zu dem Typ, in dem du damit arbeiten willst, und rechnest danach nur noch mit Zahlen. Abschnitt 13 baut genau darauf auf.

Und ein zweiter Reflex, der dazugehört: Wenn eine Rechnung ein absurdes Ergebnis liefert, ist die erste Frage nicht „stimmt meine Formel”, sondern „was für ein Typ steckt da eigentlich drin”. Ein typeof in die Eingabezeile der Console, und du weißt es, ohne eine einzige Zeile an deinem Code zu ändern.

Zum Mitnehmen

Ein Eingabefeld liefert immer Text, auch mit type="number". Wer zwei Eingaben addiert, ohne sie umzuwandeln, macht aus 5 und 5 die 55.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

Was in dieser Lektion steckt

  • Artikel mit 4 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe im Editor, direkt im Browser geprüft

    Öffnet sich mit dem Basis Konto.