Zum Inhalt
wannacode

Standardwerte

Kurz gesagt: Der Standardwert eines Parameters wird verwendet, wenn das Argument nicht übergeben wird, und ...rest sammelt beliebig viele Argumente in einem Array.

Problem

Zwei Artikel, drei Artikel

Die Kasse muss die Preise der Artikel addieren. Manchmal sind es zwei, manchmal drei. Die Funktion meint in beiden Fällen dasselbe: „addieren“. In Java und C# macht man das mit zwei Methoden, die einen Namen und unterschiedlich viele Parameter haben. Du versuchst dasselbe:

function total(a, b) {
return a + b;
}
function total(a, b, c) {
return a + b + c;
}
console.log(total(2.5, 4.0, 1.5));
console.log(total(2.5, 4.0));
Ausgabe
8
NaN

Mit drei Argumenten funktioniert es. Mit zweien bricht das Programm nicht ab, sondern gibt NaN aus („not a number“, keine Zahl). Auch mit zwei Argumenten wird also die Funktion mit drei Parametern aufgerufen. Wo ist die erste geblieben?

Die Idee

Ein Name, eine Funktion

In JavaScript wird jede function unter ihrem Namen gespeichert, bevor die erste Zeile läuft. Heißen zwei gleich, ersetzt die zweite die erste, ebenfalls noch vor der ersten Zeile. Deshalb landet schon der erste Aufruf bei der zweiten Funktion.

Deshalb kennt JavaScript kein Überladen: zwei Funktionen mit einem Namen, die sich in ihren Parametern unterscheiden, wie in Java und C#. Stattdessen kann eine Funktion unterschiedlich viele Argumente nehmen. Wie, siehst du auf den nächsten Karten.

function printHeader() {
console.log("Eckladen");
}
printHeader();
function printHeader() {
console.log("Laden am Markt");
}
printHeader();
Schritt für Schritt, in Worten
  1. Bevor es auch nur eine Zeile ausführt, speichert JavaScript jede Funktion. Der Name printHeader zeigt auf die erste.
  2. Immer noch vor der ersten Zeile: die zweite Funktion mit demselben Namen. Der Name zeigt jetzt auf sie, und die erste ist weg.
  3. Erst jetzt läuft die erste Zeile. Der Aufruf landet bei der zweiten Funktion: „Laden am Markt“.
  4. Der zweite Aufruf: wieder „Laden am Markt“.
  5. Es gibt einen Namen, und die letzte Funktion gewinnt. Deshalb gibt schon der erste Aufruf den neuen Namen aus.
Genauer, für Neugierige

Hat die Datei ein import (wie die Programme, die von der Tastatur lesen), führt Node.js sie als Modul aus. Dort sind zwei functions mit einem Namen ein Fehler, und das Programm startet nicht:

Fehler
SyntaxError: Identifier 'total' has already been declared

Das ist besser: Du siehst den Fehler sofort, statt dass still eine andere Funktion aufgerufen wird.

Probier es aus

Welche Funktion?

Was gibt das Programm aus?

function describe(x) {
console.log(`ganz: ${x}`);
}
function describe(x) {
console.log(`dezimal: ${x}`);
}
describe(5);
describe(5.0);
Antwort

Die Idee

Ein Standardwert

Eine Funktion reicht für zwei und für drei Artikel. Gib dem dritten Parameter einen Standardwert: Er wird verwendet, wenn das Argument nicht übergeben wird.

function total(a, b, c = 0) {
return a + b + c;
}
console.log(total(2.5, 4.0));
console.log(total(2.5, 4.0, 1.5));
Ausgabe
6.5
8

c = 0 bedeutet: Hat der Aufruf nur zwei Argumente, ist c gleich 0. Hat er drei, ist c das dritte.

Parameter mit Standardwert schreibt man nach denen ohne. Argumente werden den Parametern nach Position zugeordnet, also stehen die optionalen am Ende.

Genauer, für Neugierige

Der Standardwert wird bei jedem Aufruf berechnet, bei dem das Argument fehlt. Deshalb ist ein Standard-Array jedes Mal ein neues:

function addItem(item, cart = []) {
cart.push(item);
return cart;
}
console.log(addItem("Brot"));
console.log(addItem("Milch"));
Ausgabe
[ 'Brot' ]
[ 'Milch' ]

Probier es aus

Finde den Fehler

Das Programm startet, gibt aber „undefined, Nächte: Maria“ aus. In welcher Zeile ist der Fehler?

Wähle die Zeile mit dem Fehler.

Die Idee

Wie man einen Parameter überspringt

Ein Hotel nimmt Buchungen an. Eine Nacht ohne Frühstück ist am häufigsten, also sind beide Standardwerte:

function book(name, nights = 1, breakfast = false) {
console.log(`${name}, Nächte: ${nights}`);
if (breakfast) {
console.log(" mit Frühstück");
}
}
book("Maria");
book("Jonas", 3);
book("Lena", undefined, true);
Ausgabe
Maria, Nächte: 1
Jonas, Nächte: 3
Lena, Nächte: 1
mit Frühstück

Lena möchte Frühstück, aber nur eine Nacht. JavaScript hat keine Schlüsselwortargumente: Argumente gehen nur nach Position in die Parameter. Um den dritten zu erreichen, übergibst du an der Stelle des zweiten undefined. Nur undefined löst den Standardwert aus. null nicht:

book("Lena", null);
Ausgabe
Lena, Nächte: null
Genauer, für Neugierige

Gibt es viele optionale Parameter, übergibt JavaScript-Code meist ein Objekt mit Namen: { breakfast: true }. In der Funktion nimmt { nights = 1, breakfast = false } = {} jeden Wert über seinen Namen, mit Standardwert. Objekte schauen wir uns im Modul „Klassen und Objekte“ an, aber das Muster ist so verbreitet, dass du es erkennen solltest:

function book(name, { nights = 1, breakfast = false } = {}) {
console.log(`${name}, Nächte: ${nights}`);
if (breakfast) {
console.log(" mit Frühstück");
}
}
book("Maria");
book("Lena", { breakfast: true });
book("Felix", { nights: 2 });
Ausgabe
Maria, Nächte: 1
Lena, Nächte: 1
mit Frühstück
Felix, Nächte: 2

Die Idee

Beliebig viele Argumente

Und wenn es fünf Artikel sind? Zwanzig? Du schreibst nicht für jeden einen Parameter. Du sagst, dass die Funktion beliebig viele Argumente nimmt:

function total(...prices) {
let result = 0;
for (const p of prices) {
result += p;
}
return result;
}
console.log(total(1.5, 2.0, 3.5, 4.0));
console.log(total(9.99));
console.log(total());
Ausgabe
11
9.99
0

Die drei Punkte vor dem Namen (...prices) bedeuten: „Übergib so viele Werte, wie du willst.“ In der Funktion kommen sie als Array an, das auch leer sein kann. Das nennt man einen Rest-Parameter.

function show(...prices) {
console.log(prices);
}
show(1.5, 2.0);
Ausgabe
[ 1.5, 2 ]

Deshalb gibt auch console.log so viele Werte aus, wie du ihm gibst: Es ist eine Funktion, die beliebig viele Argumente nimmt.

console.log("Brot", "Milch", "Kaffee");
console.log(Math.max(3, 8, 2));
Ausgabe
Brot Milch Kaffee
8
Genauer, für Neugierige
  • Es kann nur einen solchen Parameter geben, und er muss der letzte sein: function receipt(title, ...prices).

Probier es aus

Was fehlt?

function total(prices) {
  let result = 0;
  for (const p of prices) {
    result += p;
  }
  return result;
}

Übung

Eine Funktion statt mehrerer

1. Die größte. Schreib eine Funktion, largest(...numbers), die die größte von beliebig vielen Zahlen zurückgibt.

Aufrufe
largest(3, 8)
largest(4, 9, 2)
largest(2.5, 1.5)
Ausgabe
8
9
2.5

2. Notendurchschnitt. Die Funktion average(...grades) gibt den Durchschnitt beliebig vieler Noten zurück, und ohne Noten gibt sie 0 zurück.

Aufrufe
average(5, 6, 4)
average(6, 5)
average()
Ausgabe
5
5.5
0

3. Eine Zeile auf dem Bon. printLine(item, qty) gibt „Kaffee x 2“ aus. Mach die Menge optional: Ohne sie ist sie 1.

Aufrufe
printLine("Kaffee", 2)
printLine("Croissant")
Ausgabe
Kaffee x 2
Croissant x 1

4. Kostenlose Lieferung. shippingCost(total, freeFrom = 50) gibt 0 zurück, wenn die Bestellung mindestens die Schwelle erreicht, sonst 4,99 €. Die Schwelle ist 50 €, außer es wird eine andere übergeben.

Aufrufe
shippingCost(62.0)
shippingCost(30.0)
shippingCost(30.0, 25)
Ausgabe
0
4.99
0

Test

Teste dich

1. In der Datei steht function total(a, b) { … } und darunter function total(a, b, c) { … }. Was liefert total(2, 3)?
2. function total(a, b, c = 0) { return a + b + c; } Was gibt total(2, 3) zurück?
3. Wie rufst du function book(name, nights = 1, breakfast = false) auf, damit es Frühstück gibt und die Nächte bei 1 bleiben?
4. Was ist prices in function total(...prices)?
5. Welches Programm läuft ohne Fehler, gibt aber das falsche Ergebnis aus?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·