Funktionen (Teil 1)
Dauer: 30 Minuten
- Aufbau und Verwendung von Funktionen
- Deklaration, Parameter, Rückgabewerte
- Aufruf und Verwendung von Rückgabewerten
Ziel: Funktionen geben Programmen Struktur
Wir betrachten Funktionen hier zunächst als Möglichkeit, Anweisungen zusammenzufassen und somit Struktur im Programm zu erhalten.
Funktionen sind ein mächtiges Werkzeug und wir werden später noch weitere Aspekte kennenlernen.
Mit Funktionen lassen sich Teile des ausführbaren Programmcodes zu „Unterprogrammen“ zusammenfassen.
Beispiele: Einlesen von Daten (Benutzereingaben durch die Tastatur), Formatierung einer Ausgabe auf dem Bildschirm, komplexe Berechnungen, usw.
Folgendes kann mit Funktionen erreicht werden:
- Strukturierung bzw. Modularisierung des Programms, wodurch Programme leichter nachvollziehbar werden (einfachere Lesbarkeit)
- Reduzierung des Programmieraufwands (z.B. durch Wiederverwendbarkeit bestimmter Abläufe)
- Anpassungen von Programmen werden erleichtert (bessere Wartbarkeit)
Bisherige Verwendung bzw. Aufrufe von Funktionen
Im folgenden Beispiel sind zwei Funktionsaufrufe zu sehen:
let input = prompt("Bitte Namen eingeben");
console.log(input);
Die Funktion prompt
wird mit einem Text-Parameter/-Argument
aufgerufen und wir weisen das Ergebnis bzw. den Rückgabewert
der Funktion einer Variablen input
zu.
Im Aufruf von console.log
übergeben wir input
als
Parameter/Argument an die Funktion.
Grundstruktur von Funktionen
Eine Funktion kann keine bis beliebig viele Parameter
(Argumente) haben. Eine Funktion hat immer einen
Rückgabewert (Ergebnis) — auch ohne return
. Allerdings kann dieser beim Aufruf der Funktion ignoriert werden (z.B. wenn keine Zuweisung des Rückgabewerts an eine Variable erfolgt).
Die Parameter werden durch unterschiedliche Namen in den runden Klammern angegeben (param1, param2, usw
). Rückgabewerte werden
durch return
meistens als letzte Zeile am Ende des
Funktionsrumpf angegeben.
Endet die Ausführung einer Funktion ohne return
-Anweisung, dann
wird undefined
als Ergebnis der Funktion zurückgeliefert.
Parameter und Rückgabewerte werden in JavaScript nicht mit Datentypen angegeben — dies kann nahtlos durch die Erweiterung mit TypeScript erfolgen.
Deklaration einer Funktion
Betrachten wir folgendes Beispiel:
function testFunction(firstParam, secondParam) {
let x = 0;
// Anweisungen und Berechnungen im Funktionsrumpf
x = 123 + firstParam + secondParam;
// Rückgabewert - meist am Ende der Methode
return x;
}
Somit besteht die Deklaration einer Funktion aus
- Dem Schlüsselwort
function
gefolgt von einem Namen (obentestFunction
) - den beliebig vielen Parametern der Funktion, die unterschiedliche Namen haben und mit Komma voneinander getrennt werden (oben
firstParam
undsecondParam
). - dem Funktionsrumpf zwischen
{ … }
- optional: einer
return
-Anweisung, die das Ergebnis der Funktion zurückliefert (wenn erforderlich bzw. gewünscht)
Der Funktionsrumpf steht zwischen { … }
und enthält Anweisungen.
Lokale Variablen können im Rumpf der Methode deklariert werden, sodass dies ihr Gültigkeitsbereich ist, und sie außerhalb der Funktion nicht existieren bzw. nicht bekannt sind.
Gibt es eine Variable/Konstante mit Namen myName
außerhalb der Funktion,
dann kann innerhalb der Funktion eine Variable/Konstante mit gleichem Namen myName
deklariert werden.
Funktionen können Funktionen enthalten, d.h. es ist möglich, innerhalb einer Funktion sozusagen eine „lokale“ Funktion zu deklarieren, die nur in dieser Funktion existiert.
Aufruf einer Funktion
Der Aufruf der Funktion aus obigem Beispiel erfolgt mit passenden Parametern:
testFunction(15, 26);
Achtung: es dürfen auch mehr oder weniger Parameter angegeben werden (also aufpassen!).
Beim Aufruf sollte (!) die vorgesehende Paramateranzahl mit passenden Datentypen angegeben werden.
Das Ergebnis der Funktion kann z.B. einer Variablen zugewiesen werden:
const result = testFunction(15, 26);
Danach steht das Ergebnis bzw. der Rückgabewert des
Funktionsaufrufs in der Konstanten result
zur weiteren
Verwendung bereit.
Auch wenn eine Funktion erst später oder am Ende eines Skripts bzw. der Datei deklariert wird, dann kann diese schon zuvor aufgerufen werden:
test(); // Aufruf einer Funktion...
// ... die erst „später“ deklariert wird
function test() {
console.log("Test!");
}
Dennoch ist es in der Regel empfehlenswert, Funktionen am Anfang einer Datei zu deklarieren, damit der Code übersichtlicher, lesbarer und leichter nachzuvollziehen ist.
Ablauf des Funktionsaufrufs im Detail
Zur Veranschaulichung des Ablaufs eines Funktionsaufrufs soll die folgende grobe Darstellung dienen:
- Initialisiere die Parameter der Funktion mit den Werten der aktuellen Parameter wie sie beim Aufruf angegeben sind.
- Führe den Rumpf der Funktion aus.
- Falls vorhanden, gib den Rückgabewert (Ergebniswert) zurück.
- Vernichte alle lokalen Variablen und Parameter-Variablen der Funktion.
Was bedeutet dies für die Parameter?
- Die Funktion arbeitet mit Kopien der aktuellen Parameter.
- Wenn also Variablen als Parameter im Aufruf einer Funktion verwendet werden, dann ändern sich diese Variablen nicht durch die Anweisungen in der Funktion.
- Dies wird „call-by-value“ genannt, weil nur die Werte und nicht Referenzen an Funktionen übergeben werden.
Bemerkung zu Parametern
Funktionen erhalten Parameter als Kopien der Werte (call-by-value), d.h. Zuweisungen an Parameter habe keine Auswirkung außerhalb der Funktion.
Änderungen an Eigenschaften von Objekt-Parametern wirken sich aber aus!
Es folgt ein Beispiel, dass evtl. erst später nachvollziehbar wird nachdem wir Objekte in JavaScript besprochen haben.
function changeStuff(a, b, c) {
a = a * 10;
b.item = "changed";
c = {item: "changed"};
}
let num=10, obj1={item: "unchanged"}, obj2={item: "unchanged"};
changeStuff(num, obj1, obj2);
console.log(num); // 10 (also unverändert)
console.log(obj1.item); // "changed"
console.log(obj2.item); // "unchanged"
Quelle dazu bei stackoverflow