JavaScript - Schließungen

Hallo da draußen, zukünftige Codingsuperstars! ? Heute machen wir uns auf eine aufregende Reise in die Welt der JavaScript-Schließungen. Keine Sorge, wenn das ein bisschen einschüchternd klingt – ich verspreche, dass ihr am Ende dieses Tutorials Schließungs-Experten sein werdet! Also holt euch eure Lieblingsgetränke, settle down, und Tauchen wir ein!

JavaScript - Closures

Was ist eine Schließung?

Stellt euch vor, ihr habt eine magische Box, die sich an alles erinnert, was drin ist, auch wenn ihr sie schließt. Das ist im Grunde genommen, was eine Schließung in JavaScript ist!

Eine Schließung ist eine Funktion, die auf Variablen in ihrem äußeren (umgebenden) lexikalischen Gültigkeitsbereich zugreifen kann, selbst wenn die äußere Funktion bereits zurückgegeben hat. Es ist so, als trägt die Funktion einen kleinen Rucksack mit Variablen herum, die sie immer dann verwenden kann, wenn sie sie braucht.

Schauen wir uns ein einfaches Beispiel an:

function outerFunction(x) {
let y = 10;
function innerFunction() {
console.log(x + y);
}
return innerFunction;
}

let closure = outerFunction(5);
closure(); // Ausgabe: 15

In diesem Beispiel ist innerFunction eine Schließung. Sie "erinnert" sich an die Werte von x und y, auch nach dem Beenden der Ausführung von outerFunction.

Lexikaler Gültigkeitsbereich

Bevor wir tiefer in Schließungen einsteigen, müssen wir den lexikalischen Gültigkeitsbereich verstehen. Das ist ein schicker Ausdruck, der einfach bedeutet, dass eine Funktion auf Variablen aus ihrem äußeren Gültigkeitsbereich zugreifen kann.

let name = "Alice";

function greet() {
console.log("Hello, " + name + "!");
}

greet(); // Ausgabe: Hello, Alice!

Hier kann greet auf die Variable name zugreifen, weil lexikaler Gültigkeitsbereich existiert. Es ist so, als könnte greet alles in seiner Umgebung sehen.

Geschachtelte Funktion

Schließungen sind oft mit geschachtelten Funktionen verbunden. Schauen wir uns ein Beispiel an:

function outer() {
let count = 0;
function inner() {
count++;
console.log(count);
}
return inner;
}

let counter = outer();
counter(); // Ausgabe: 1
counter(); // Ausgabe: 2

Hier ist inner in outer eingebettet. Das Magische passiert, weil inner sich an die Variable count aus ihrem äußeren Gültigkeitsbereich erinnert, auch nach dem Beenden der Ausführung von outer.

Rückgabefunktion

Eine der coolen Eigenschaften von JavaScript ist, dass Funktionen andere Funktionen zurückgeben können. Dies ist ein wichtiger Aspekt von Schließungen.

function multiplier(x) {
return function(y) {
return x * y;
};
}

let double = multiplier(2);
console.log(double(5)); // Ausgabe: 10
console.log(double(3)); // Ausgabe: 6

In diesem Beispiel gibt multiplier eine Funktion zurück, die den Wert von x "erinnert". Diese zurückgegebene Funktion ist eine Schließung.

Ein Zähler-Dilemma

Schauen wir uns ein gängiges Problem an, das Schließungen lösen können:

function createCounter() {
let count = 0;
return {
increment: function() {
count++;
},
getCount: function() {
return count;
}
};
}

let counter = createCounter();
counter.increment();
counter.increment();
console.log(counter.getCount()); // Ausgabe: 2

Hier ermöglicht die Schließung private Variablen (count), die nur über die bereitgestellten Methoden zugänglich sind.

Beispiel: JavaScript-Schließungen

Tauchen wir in ein komplexeres Beispiel ein, um unser Verständnis wirklich zu festigen:

function makeAdder(x) {
return function(y) {
return x + y;
};
}

let add5 = makeAdder(5);
let add10 = makeAdder(10);

console.log(add5(2));  // Ausgabe: 7
console.log(add10(2)); // Ausgabe: 12

In diesem Beispiel erstellt makeAdder eine Schließung, die den Wert von x "erinnert". Wir können mehrere Adder-Funktionen mit unterschiedlichen vordefinierten Werten erstellen.

Beispiel

Hier ist ein weiteres praktisches Beispiel für Schließungen:

function createGreeter(greeting) {
return function(name) {
console.log(greeting + ", " + name + "!");
};
}

let greetHello = createGreeter("Hello");
let greetHi = createGreeter("Hi");

greetHello("Alice"); // Ausgabe: Hello, Alice!
greetHi("Bob");      // Ausgabe: Hi, Bob!

Dieses Beispiel zeigt, wie Schließungen verwendet werden können, um angepasste Funktionen zu erstellen.

Vorteile von Schließungen

Schließungen bieten mehrere Vorteile:

  1. Daten Privatsphäre
  2. Funktionssfabriken
  3. Erhaltung des Zustands

Schauen wir uns diese in einer Tabelle an:

Vorteil Beschreibung Beispiel
Daten Privatsphäre Schließungen können private Variablen erstellen function counter() { let count = 0; return { increment: () => ++count, getValue: () => count }; }
Funktionssfabriken Erstellen von Funktionen mit vordefinierten Parametern function multiply(x) { return (y) => x * y; }
Erhaltung des Zustands Verfolgen von Daten über mehrere Funktionsaufrufe hinweg function createGame() { let score = 0; return { addPoint: () => ++score, getScore: () => score }; }

Und das war's, Leute! Wir haben die Welt der Schließungen durchquert, von den Grundlagen bis zu einigen fortgeschritteneren Konzepten. Denkt daran, wie jede Fähigkeit, erfordert das Beherrschen von Schließungen Übung. Also lasst euch nicht entmutigen, wenn es nicht sofort klickt – weiter codieren, weiter experimentieren, und bald werdet ihr die Macht der Schließungen wie ein wahrer JavaScript-Zauberer einsetzen können! ?‍♂️✨

Credits: Image by storyset