Switch statement – Programmieren lernen mit JavaScript – Thytos
Nächstes Video startet in 3 Sekunden.
Programmieren lernen mit JavaScript

Switch statement

Das switch-Konstrukt ist dazu da, für ver­schie­de­ne Fäl­le ei­nes Aus­drucks ver­schie­de­ne An­wei­sun­gen zu de­fi­nie­ren.

Das Date-Objekt besitzt die Methode getMonth, die den Index des Monats zurückgibt. Wie würdet ihr eine Funktion schreiben, die ein Datum übergeben bekommt und den Monatsnamen des Datums zurückgibt?

function getMonthName(date) {
  …
}

camelCase

Der Funktionsname lautet getMonthName. Er besteht aus den drei Wörtern get month name, zu Deutsch Monatsnamen auslesen, die zu einem Namen zusammengeschrieben sind.

In Funktions-, Variablen- und Propertynamen dürfen keine Leerzeichen vorkommen. Wenn ein Name aus mehreren Worten besteht, müssen diese Worte zusammengeschrieben werden. Um dennoch die Wortgrenzen zu kennzeichnen, gibt es verschiedene Möglichkeiten.

snake_case // Worte durch Unterstriche trennen
kebap-case // Worte durch Bindestriche trennen
camelCase // Worte durch Großbuchstaben trennen

Zum Beispiel könnten Unterstriche verwendet werden, um die Worte voneinander abzugrenzen. Es gibt Programmiersprachen, in denen das gemacht wird: PHP beispielsweise und Ruby.
In JavaScript wäre das technisch möglich, allerdings nicht üblich. Stattdessen ist es Konvention, camel case einzusetzen. Hierbei werden die Worte zusammengeschrieben, aber der Anfangsbuchstabe eines Wortes groß, sodass dadurch die Wortgrenzen markiert sind. Weil innerhalb eines Namens die Großbuchstaben wie Höcker eines Kamels herausragen, heißt die Schreibweise camel case, frei übersetzt Kamel Schreibweise.

Die Binnenmajuskel, so der richtige Name im Deutschen, schauen wie Kamelhöcker hervor

Implementierung mit if…else if

Eine Möglichkeit, die Funktion zu implementieren, ist über ein großes if-Konstrukt.

function getMonthName(date) {
  var monthIndex = date.getMonth();
  var monthName;
  if (monthIndex === 0) {
    monthName = "Januar";
  } else if (monthIndex === 1) {
    monthName = "Februar";
  } else if (monthIndex === 2) {
    monthName = "März";
  } else if (monthIndex === 3) {
    monthName = "April";
  } else if (monthIndex === 4) {
    monthName = "Mai";
  } else if (monthIndex === 5) {
    monthName = "Juni";
  } else if (monthIndex === 6) {
    monthName = "Juli";
  } else if (monthIndex === 7) {
    monthName = "August";
  } else if (monthIndex === 8) {
    monthName = "September";
  } else if (monthIndex === 9) {
    monthName = "Oktober";
  } else if (monthIndex === 10) {
    monthName = "November";
  } else if (monthIndex === 11) {
    monthName = "Dezember";
  } else {
    monthName = "Ungültiges Datum";
  }
  return monthName;
}

getMonthName(new Date());
// => "Juli"

getMonthName(new Date(2017, 5));
// => "Juni"

Hierbei fällt auf, dass der Code sehr repetitiv wirkt: Es wird dieselbe Variable, derselbe Ausdruck, unterschiedlichen Fällen gegenübergestellt.
Wenn so ein Muster in eurem Code auftaucht, gibt es dafür eine bessere Kontrollstruktur.

Implementierung mit switch

Das switch-Konstrukt ist genau für diesen Fall ausgelegt. Im Kopf des Konstrukts wird ein Ausdruck angegeben, beispielsweise ein Variablenname. Im Körper des Konstrukts sind eine Reihe von Fällen aufgeführt, die nacheinander abgegangen werden. Entspricht der Ausdruck einem Fall, wird der Code für diesen Fall ausgeführt.

function getMonthName(date) {
  var monthName;
  switch (date.getMonth()) {
    case 0: monthName = "Januar";
    case 1: monthName = "Februar";
    case 2: monthName = "März";
    case 3: monthName = "April";
    case 4: monthName = "Mai";
    case 5: monthName = "Juni";
    case 6: monthName = "Juli";
    case 7: monthName = "August";
    case 8: monthName = "September";
    case 9: monthName = "Oktober";
    case 10: monthName = "November";
    case 11: monthName = "Dezember";
    default: monthName = "Ungültiges Datum";
  }
  return monthName;
}

Mit default kann zusätzlich Code angegeben werden, der ausgeführt wird, wenn keiner der Fälle zutrifft – vergleichbar mit dem else in einem if-Konstrukt.
Der Code ist kürzer und etwas lesbarer. Doch es gibt ein Problem. Egal mit welchem Datum ihr testet, die Funktion gibt immer zurück, dass es ein ungültiges Datum sei.

getMonthName(new Date());
// => "Ungültiges Datum"

getMonthName(new Date(2017, 5));
// => "Ungültiges Datum"

(new Date(2017, 5)).getMonth(); // Es ist aber gültig!
// => 5

Die Daten sind gültig. Wieso wird also diese Meldung zurückgegeben?

Wenn ein Fall im switch-Konstrukt zutrifft, wird nicht nur dessen Code ausgeführt, sondern ab da auch jeder weitere. Dieses Fall through-Verhalten, zu Deutsch Durchfall-Verhalten (der Englische Begriff ist hier weniger missverständlich), ist irreführend, in der Regel unerwünscht und stellt oft eine Fehlerquelle dar.

Um das Verhalten zu vermeiden, muss am Ende jedes Code-Blocks ein break; geschrieben werden. Beim default kann es weggelassen werden, da es ohnehin die letzte Anweisung ist und danach kein weiterer Fall mehr folgt.

function getMonthName(date) {
  var monthName;
  switch (date.getMonth()) {
    case 0: monthName = "Januar"; break;
    case 1: monthName = "Februar"; break;
    case 2: monthName = "März"; break;
    case 3: monthName = "April"; break;
    case 4: monthName = "Mai"; break;
    case 5: monthName = "Juni"; break;
    case 6: monthName = "Juli"; break;
    case 7: monthName = "August"; break;
    case 8: monthName = "September"; break;
    case 9: monthName = "Oktober"; break;
    case 10: monthName = "November"; break;
    case 11: monthName = "Dezember"; break;
    default: monthName = "Ungültiges Datum";
  }
  return monthName;
}

getMonthName(new Date());
// => "Juli"

getMonthName(new Date(2017, 5));
// => "Juni"

Jetzt entspricht das Ergebnis den Erwartungen.

Statt break zu verwenden, kann in diesem Fall auch return eingesetzt werden, weil dadurch die Ausführung der Funktion an der Stelle beendet wird und somit ebenfalls keine weiteren Fälle abgegangen werden.

function getMonthName(date) {
  switch (date.getMonth()) {
    case 0: return "Januar";
    case 1: return "Februar";
    case 2: return "März";
    case 3: return "April";
    case 4: return "Mai";
    case 5: return "Juni";
    case 6: return "Juli";
    case 7: return "August";
    case 8: return "September";
    case 9: return "Oktober";
    case 10: return "November";
    case 11: return "Dezember";
    default: return "Ungültiges Datum";
  }
}

getMonthName(new Date());
// => "Juli"

getMonthName(new Date(2017, 5));
// => "Juni"

Implementierung über ein Array

Die kürzeste Variante läuft ohne if und ohne switch: Da der Monatsindex wie ein Arrayindex bei Null beginnt und jedem Index ein konkreter Wert zugeordnet ist, kann auch ein Array dafür verwendet werden.

function getMonthName(date) {
  var monthNames = "Januar Februar März April Mai Juni Juli August September Oktober November Dezember".split(" ");
  return monthNames[date.getMonth()];
}

getMonthName(new Date());
// => "Juli"

getMonthName(new Date(2017, 5));
// => "Juni"

Das Array mit den Monatsnamen könnte auch außerhalb der Funktion definiert sein, um so nicht bei jedem Funktionsaufruf neu generiert zu werden. Diese Lösung ist die kürzeste und direkteste.