ƒFunktionen

Funktionen sind in JavaScript ganz normale Werte („First-Class-Objekte“). Hier: Schreibweisen, Parameter, Destructuring, Spread, Template-Literals – und was beim Aufruf auf dem Call Stack passiert.

✍️Deklaration, Ausdruck, Arrow

Drei Schreibweisen

1function addiere(a, b) { // Deklaration (gehoistet)
2 return a + b;
3}
4const mal = function (a, b) { // Funktionsausdruck
5 return a * b;
6};
7const minus = (a, b) => a - b; // Arrow-Funktion
8console.log(addiere(2, 3), mal(2, 3), minus(2, 3));
9console.log(typeof minus, minus.length, minus.name);
Konsole (echt ausgeführt)
wird ausgeführt …

Arrow-Funktionen haben kein eigenes this, kein arguments und können nicht mit new aufgerufen werden.

DeklarationAusdruckArrow
vor Definition aufrufbarja (Hoisting)neinnein
eigenes thisjajanein (lexikalisch)
argumentsjajanein
mit new aufrufbarjajanein
kurze Form––x => x * 2

🎛️Parameter, Destructuring, Spread, Template-Literals

Default- und Rest-Parameter

1function gruss(name = "Gast", ...rest) {
2 console.log(`Hallo ${name}`, rest);
3}
4gruss();
5gruss("Ada", 1, 2);
6gruss(undefined); // undefined → Standardwert
7gruss(null); // null nicht!
Konsole (echt ausgeführt)
wird ausgeführt …

Der Standardwert greift nur bei undefined. ...rest sammelt alle übrigen Argumente in einem echten Array.

Destructuring

1const [erst, , dritt = 0, ...rest] = [10, 20, 30, 40, 50];
2console.log(erst, dritt, rest);
3
4const { name, alter: jahre = 18, ort = "?" } = { name: "Ada", alter: 36 };
5console.log(name, jahre, ort);
6
7let a = 1, b = 2;
8[a, b] = [b, a]; // Tauschen ohne Hilfsvariable
9console.log(a, b);
Konsole (echt ausgeführt)
wird ausgeführt …

Spread ...

1const a = [1, 2];
2const b = [...a, 3]; // Array kopieren/erweitern
3console.log(b, Math.max(...b));
4const basis = { farbe: "rot", groesse: "M" };
5const neu = { ...basis, groesse: "L" }; // spätere gewinnt
6console.log(neu);
7const kopie = { ...basis, tags: ["x"] };
8console.log(kopie.tags === basis.tags);
Konsole (echt ausgeführt)
wird ausgeführt …

Spread erzeugt eine flache Kopie. Für tiefe Kopien gibt es structuredClone().

Template-Literals

1const artikel = "Buch", preis = 12.5;
2console.log(`${artikel}: ${preis.toFixed(2)} €`);
3console.log(`Zeile 1
4Zeile 2`);
5console.log(`2 + 3 = ${2 + 3}`);
Konsole (echt ausgeführt)
wird ausgeführt …

Backticks erlauben Ausdrücke in ${…} und echte Zeilenumbrüche.

🧩Funktionen als Werte

Funktionen höherer Ordnung

1const mal = (faktor) => (x) => x * faktor; // gibt eine Funktion zurück
2const verdreifache = mal(3);
3console.log(verdreifache(7));
4console.log([1, 2, 3].map(mal(10)));
Konsole (echt ausgeführt)
wird ausgeführt …

Funktionen sind Werte: Man kann sie übergeben, zurückgeben und in Variablen speichern.

Rest oder Spread?

Die drei Punkte bedeuten je nach Position das Gegenteil:

function f(...args) {}   // Rest: sammelt → Array
f(...[1, 2, 3]);          // Spread: verteilt ← Array
const [a, ...rest] = xs;  // Rest im Destructuring
const kopie = { ...obj }; // Spread im Objektliteral

Merkregel: links vom = bzw. in der Parameterliste wird gesammelt, rechts bzw. beim Aufruf wird verteilt.

📚Rekursion auf dem Call Stack

Jeder Funktionsaufruf legt einen Frame auf den Call Stack; return nimmt ihn wieder herunter. Die Werte werden hier berechnet – wähle N.
Schritt 1 / 13 · Tasten ← →
1function fakultaet(n) {
2 if (n <= 1) return 1;
3 return n * fakultaet(n - 1);
4}
5console.log(fakultaet(4));
Das Skript ruft fakultaet(4) auf.
(Konsole leer)
Call Stack (oben = läuft gerade)
Skript

Jeder Aufruf bekommt einen eigenen Frame mit eigenen Variablen. Ohne Abbruchbedingung wächst der Stack, bis „RangeError: Maximum call stack size exceeded“ kommt.