Abschnitt 5 · Lektion 5
Standardwerte und beliebig viele Argumente
Zwei Werkzeuge für dasselbe Problem: Eine Funktion soll auch dann etwas Sinnvolles tun, wenn nicht genau so viele Argumente kommen, wie sie Parameter hat.
Der Standardwert
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> function gruss(name = "Gast") {
return `Hallo, ${name}!`;
}
console.log(gruss("Mario"));
console.log(gruss());
console.log(gruss(undefined));
// Und hier hört es auf: null ist ein Wert, kein fehlendes Argument.
console.log(gruss(null));
console.log(gruss(""));
// Der Standardwert darf auch eine Rechnung sein. Sie läuft erst,
// wenn sie wirklich gebraucht wird.
function preis(netto, brutto = netto * 1.19) {
return `${netto} netto, ${brutto} brutto`;
}
console.log(preis(100));
console.log(preis(100, 150)); Hinter einen Parameter darf ein Gleichheitszeichen und ein Wert. Der wird eingesetzt, wenn beim Aufruf nichts kommt.
Damit erledigt sich das undefined-Problem aus Lektion 5.2 an der Stelle, an der es entsteht. Statt später zu prüfen, ob etwas fehlt, steht die Antwort in der Signatur, und wer die Funktion liest, sieht sofort, was sie ohne Argument tut.
Die Regel, die man kennen muss: Der Standardwert greift bei undefined und sonst nie. Bei null greift er nicht, bei einem leeren Text nicht, bei 0 nicht, bei false nicht. Das ist Absicht und der Unterschied zu dem, was du mit || aus Lektion 3.4 bauen würdest: Dort wäre 0 schon zu wenig.
Der Standardwert darf auch eine Rechnung sein, und er darf sich auf Parameter beziehen, die weiter links stehen. Die Rechnung läuft erst, wenn sie gebraucht wird, also nur bei einem fehlenden Argument.
Nach hinten damit
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // Der Standardwert steht vorn. Um den zweiten Wert zu setzen,
// muss man den ersten überspringen, und das geht nur mit undefined.
function trennerVorn(zeichen = "-", anzahl) {
return zeichen.repeat(anzahl);
}
console.log(trennerVorn(undefined, 5));
// Steht er hinten, ruft man einfach mit weniger Argumenten auf.
function trennerHinten(anzahl, zeichen = "-") {
return zeichen.repeat(anzahl);
}
console.log(trennerHinten(5));
console.log(trennerHinten(5, "*")); Weil Argumente stur von links nach rechts zugeordnet werden, hat die Reihenfolge eine Folge, die man einmal gesehen haben muss.
Steht ein Parameter mit Standardwert vor einem ohne, kommst du an den hinteren nur heran, indem du für den vorderen ausdrücklich undefined übergibst. Das ist erlaubt, sieht aber aus wie ein Versehen.
Deshalb die Faustregel: Parameter mit Standardwert stehen hinten. Vorne das, was gebraucht wird, hinten das, was optional ist. Dann ruft man die Funktion in der einfachen Form mit weniger Argumenten auf, und genau das ist der Sinn der Sache.
Beliebig viele Argumente
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // Die drei Punkte sammeln alle Argumente in einer Liste.
function zaehle(...werte) {
console.log("Bekommen:", werte);
console.log("Anzahl:", werte.length);
console.log("Der erste:", werte[0]);
return werte.length;
}
zaehle("a", "b", "c");
zaehle(1);
zaehle();
// Über die Liste läuft man wie über jede Zählschleife: von 0 bis
// unter length, und werte[i] holt den Eintrag an der Stelle i.
function summe(...zahlen) {
let gesamt = 0;
for (let i = 0; i < zahlen.length; i++) {
gesamt += zahlen[i];
}
return gesamt;
}
console.log("Summe:", summe(1, 2, 3, 4)); Manchmal steht vorher nicht fest, wie viele Werte kommen. Eine Summe über drei Zahlen und eine über zwanzig sollen nicht zwei Funktionen sein.
Dafür gibt es den Rest-Parameter: drei Punkte vor dem Namen, und die Funktion sammelt alle übrigen Argumente in einer Liste. Kommt gar nichts, ist die Liste leer, und die Funktion läuft trotzdem.
Um Listen geht es richtig erst in Abschnitt 6. Für hier reichen drei Dinge: werte.length sagt, wie viele es sind, werte[0] ist der erste Eintrag, und mit einer Zählschleife von 0 bis unter length läufst du alle durch. Das ist dieselbe Schleife wie in Lektion 4.1, nur dass die Obergrenze aus der Liste kommt.
Der Rest steht zuletzt
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // Der erste Wert hat eine eigene Bedeutung, alles danach ist Liste.
function liste(titel, ...eintraege) {
console.log(titel);
for (let i = 0; i < eintraege.length; i++) {
console.log(` ${i + 1}. ${eintraege[i]}`);
}
return eintraege.length;
}
liste("Einkaufszettel", "Brot", "Milch", "Kaffee");
liste("Leere Liste");
// Der Rest steht immer zuletzt und nur einmal. Etwas wie
// (...a, ...b) gibt es nicht: es wäre nicht zu entscheiden,
// wo das eine aufhört und das andere anfängt. Vor dem Rest-Parameter dürfen ganz normale Parameter stehen. Sie bekommen ihre Werte zuerst, alles Weitere landet in der Liste.
Das ist die übliche Form: Der erste Wert hat eine eigene Bedeutung, der Rest ist Aufzählung. Genau so sieht console.log selbst aus.
Zwei Einschränkungen: Der Rest-Parameter steht immer zuletzt, und es gibt nur einen davon. Beides folgt aus derselben Überlegung, denn bei zwei Listen wäre nicht zu entscheiden, wo die eine aufhört.
Zum Schluss ein historischer Hinweis, damit du ihn in altem Code einordnen kannst: Früher gab es dafür eine Variable namens arguments, die in jeder Funktion von selbst zur Verfügung stand. Sie ist keine echte Liste, sie steht in Arrow Functions gar nicht zur Verfügung, und sie sagt in der Signatur nichts. Der Rest-Parameter ersetzt sie vollständig.
Zum Mitnehmen
Ein Standardwert springt nur ein, wenn das Argument fehlt oder undefined ist. Bei null bleibt es bei null.
Jetzt du
Basis Konto, kostenlosZu 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.