Alle Funktionen liefern einen Rückgabewert. Wenn man ihn nicht selbst bestimmt ist der Rückgabewert undefined.
Man kann aber diesen Rückgabewert selbst bestimmen. Das hat den Vorteil, dass man diese Funktion als Ausdruck verwenden kann. Soll heißen, man kann sie beispielsweise einer
Variablen zuweisen.
let a = zufall(1,4);
Nehmen wir an, die Funktion liefert einen Zufallswert von 1 bis 4, so kann man sie auf diese Weise gleich da wo
man den Wert braucht zuweisen.
<script>
function addition(a, b, c) {
return a + b + c;
}
</script>
Mittels return liefert die Funktion einen Rückgabewert (Ausdruck).
console.log(addition(20, 3, 5));
Eine Funktion kann immer nur einen Rückgabewert zurück geben. Dieser eine Wert kann aber auch ein Array oder Object mehreren Werten sein. mehr dazu unten
Wenn man return ohne Wert notiert, liefert die Funktion undefined.
Sobald die return Anweisung in der Funktion erscheint, wird die Funktion abgebrochen, alle
weiteren Anweisungen die nach return erscheinen, werden nicht ausgeführt. Im folgenden Beispiel wird alert nicht
ausgeführt. So etwas macht man beispielsweise mit if-Strukturen, wie im nächsten Beispiel.
function addition(a) {
return a;
alert("hallo");
}
Der Abbruch der Funktion durch return ermöglicht es auch, rekursive Funktionen zu erstellen. Das sind Funktionen, die sich immer wieder selber aufrufen. Mittels einer if Struktur wird die Anzahl der Aufrufe kontrolliert. Das wird oftmals mit einem Timer verwendet, um einen Countdown zu erzeugen.
let a1 = document.getElementById("anzeige");
function fakultaet(n){
a1.innerHTML += (n + "<br>");
if(n > 0){
return fakultaet(n-1);
}
}
fakultaet(5);
In diesem Beispiel muss ein HTML-Element vorhanden sein, mit der id="anzeige".
Das Element wird in der Variablen a1 gespeichert.
let a1 = document.getElementById("anzeige");
Die Funktion fakultaet(10) wird mit dem Wert 10 aufgerufen. Die erste Anweisung in der Funktion
schreibt dieses Argument 10 in das HTML Element. Durch += wird der eventuell vorhandene Inhalt des HTML-
Elements nicht überschrieben sondern es wird angehängt.
a1.innerHTML += (n + "<br>");
Dann wird abgefragt ob n größer als 0 ist. In dem Fall wird die Funktion erneut aufgerufen, diesmal mit einem
Wert, der um eins kleiner ist, als zuvor. Also beim zweiten mal mit 9 und so weiter. Erst wenn die 0 erreicht
ist, wird die Funktion fakultaet() nicht mehr aufgerufen.
Mit return kann man nur einen Wert zurück geben. Möchte man jedoch mehrere Werte zurück geben, kann man diese in ein Array [] oder ein Objekt {} verpacken. Um diese Werte abzuholen, gibt es zwei Wege: den "alten" Weg über den Index oder bei Objekten über den Key und den modernen Weg über das Destructuring.
function berechneRechteck(breite, hoehe) {
let flaeche = breite * hoehe;
let umfang = 2 * (breite + hoehe);
return [flaeche, umfang]; // Rückgabe als Array
}
Das ist die eleganteste Methode. Du "entpackst" das Array direkt bei der Zuweisung in einzelne Variablen. Das sieht fast so aus, als würdest du das Array rückwärts schreiben.
const [meineFlaeche, meinUmfang] = berechneRechteck(10, 5); console.log(meineFlaeche); // 50 console.log(meinUmfang); // 30
Der Vorteil: Du vergibst sofort aussagekräftige Namen für die Rückgabewerte, anstatt mit ergebnis[0] zu arbeiten.
Falls du das Destructuring nicht nutzen möchtest, kannst du das Array ganz normal in einer Variable speichern und dann über den Index darauf zugreifen.
const ergebnis = berechneRechteck(10, 5); let f = ergebnis[0]; let u = ergebnis[1];
Wenn du mehr als zwei Werte hast oder die Reihenfolge nicht auswendig lernen willst, ist es oft noch besser, ein Objekt zurückzugeben. Das ist bei Web-Entwicklern sehr beliebt:
Warum Objekt statt Array?
function berechne(zahl) {
return {
quadrat: zahl * zahl,
hälfte: zahl / 2
};
}
// 1. Das Objekt abholen let daten = berechne(4); // 2. Über den Namen (Key) zugreifen let q = daten.quadrat; // oder daten["quadrat"] let h = daten.hälfte; // oder daten["hälfte"]
const {quadrat , hälfte} = berechne(4);
Was ist Destructing, was geschieht da. Dazu hier ein einfaches Beispiel
let person = {
vorname: "Michael",
nachname: "Albers"
}
let {vorname, nachname} = person;
console.log(vorname)//Michael
Stell es dir wie eine automatische Zuweisung vor: Anstatt mühsam zwei Zeilen zu schreiben
(let vorname = person.vorname;...), sagst du JavaScript in einer Zeile: "Schau in das Objekt person, such die
Schlüssel vorname und nachname und erstelle mir gleichnamige Variablen daraus."
Das funktioniert auch bei Arrays.
let person = ["Michael", "Albers"]; let [vorname, nachname] = person;
Es kommt darauf an, auf welcher Seite des Gleichheitszeichens (=) die Klammern stehen:
Rechts vom = (Konstruktion): Hier baust du etwas zusammen.
let person = ["Michael", "Albers"]; ☞ "Erstelle mir ein echtes Array-Objekt im Speicher."
Links vom = (Destrukturierung): Hier baust du nichts zusammen, sondern du definierst ein Muster.
let [vorname, nachname] = ... ☞ "Das hier ist kein Array, sondern eine Anweisung, wie die rechte Seite entpackt werden soll."
Wenn du let [vorname, nachname] = ... schreibst, nutzt du eine Kurzschreibweise, die JavaScript intern sofort übersetzt.
Was du schreibst:
let [vorname, nachname] = ["Michael", "Albers"]; console.log(vorname)//Michael
Was JavaScript daraus macht (intern):
Erstelle eine Variable namens vorname.
Schau in das Array auf die Position 0 und weise den Wert vorname zu.
Erstelle eine Variable namens nachname.
Schau in das Array auf die Position 1 und weise den Wert nachname zu.
Es ist also kein "Array im globalen Scope", sondern eine Massen-Deklaration von Variablen. Die eckigen Klammern links sagen dem Interpreter nur: "Achtung, jetzt kommen gleich mehrere Namen für Variablen, die du bitte aus der Struktur rechts befüllst."
Hier liegt der entscheidende Punkt, warum man das eine oder das andere wählt:
Da ein Array keine Namen für seine Schubladen hat, entscheidet JavaScript nach der Position:
let [a, b] = ["Eins", "Zwei"]; // a wird immer "Eins", weil es an erster Stelle steht.
In einem Objekt haben die Schubladen Namen. JavaScript sucht im Objekt nach dem exakten Namen, den du in die geschweifte Klammer schreibst:
let { nachname, vorname } = { vorname: "Michael", nachname: "Albers" };
// Hier ist die Reihenfolge völlig egal!
// JavaScript findet "nachname", egal ob es vorne oder hinten steht.
Wenn du schreibst:
let [x, y] = [1, 2];
Gibt es danach im globalen Scope kein Array namens [x, y]. Es gibt lediglich zwei ganz normale, einzelne Variablen: x und y. Die Klammern sind in diesem Moment nur ein "Werkzeug" zum Auspacken, das danach sofort wieder verschwindet.
Ein Merksatz, der mir geholfen hat:
Die Klammern auf der linken Seite sind wie eine Schablone. Du legst sie über das Paket auf der rechten Seite, und alles, was durch die Löcher der Schablone sichtbar ist, bekommt einen eigenen Variablennamen.
Stell dir das Gleichheitszeichen wie eine Grenze vor:
| Rechts vom = (Die Fabrik) | Links vom = (Die Schablone) |
| [1, 2] erstellt ein neues Array. | [a, b] erstellt Variablen. |
| {x: 10} erstellt ein neues Objekt. | {x} sucht den Wert von x. |
| Hier gibst du Daten ein. | Hier holst du Daten heraus. |