Skip to Content

Funktionen (Teil 1)

Dauer: 60 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 (z. B. Arrow-Funktionen, Funktionen als Parameter, usw.).

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:

import { question } from 'readline-sync'; const input = question("Bitte Namen eingeben"); console.log(input);

Die Funktion question (aus readline-sync) 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).

Grundstruktur von Funktionen

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 Funktionsrumpfs 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 Funktion return x; }

Somit besteht die Deklaration einer Funktion aus

  • Dem Schlüsselwort function gefolgt von einem Namen (oben testFunction)
  • den beliebig vielen Parametern der Funktion, die unterschiedliche Namen haben und mit Komma voneinander getrennt werden (oben firstParam und secondParam).
  • 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 Funktion 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.

Es handelt sich dann aber um zwei verschiedene Variablen mit gleichem Namen.

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 vorgesehene Parameteranzahl 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 Funktionsdeklaration erst später oder am Ende eines Skripts bzw. der Datei steht, kann sie (Hoisting) schon zuvor aufgerufen werden:

test(); // Aufruf einer Funktion... // ... die erst „später“ deklariert wird function test() { console.log("Test!"); }

Das gilt nicht für Funktionsausdrücke oder Arrow-Funktionen; dennoch ist es in der Regel empfehlenswert, Funktionen am Anfang einer Datei zu deklarieren, damit der Code übersichtlicher, lesbarer und leichter nachzuvollziehen ist.

👨🏻‍💻

In der gemeinsam entwickelten Wetter-App nutzen wir Funktionen für die Eingabe, die „Ermittlung“ und die Ausgabe der Wetterdaten, z. B.

  • getLocation()
  • getTemperature()
  • displayWeather()

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 (bei Objekten: Referenzwerte) und nicht die Variablen selbst übergeben werden.

Bei Objekten als Parameter gilt eine Besonderheit: Änderungen an Eigenschaften eines Objekt-Parameters wirken sich auch außerhalb der Funktion aus. Dies wird verständlicher, wenn wir später Objektreferenzen behandeln.