Closures in JavaScript

Closures in JavaScript

Dieser Artikel erklärt Closures in JavaScript.

YouTube Video

Closures in JavaScript

In JavaScript ist ein ‚Closure‘ eines der sehr wichtigen und leistungsstarken Konzepte. Durch das Verständnis von Closures gewinnst du Wissen, das in vielen Situationen nützlich ist, etwa im Hinblick auf das Verhalten und den Gültigkeitsbereich von Funktionen sowie für asynchrone Verarbeitung und Ereignisbehandlung in JavaScript. Hier erklären wir im Detail alles von der grundlegenden Definition von Closures bis hin zu konkreten Beispielen und deren Anwendungen.

Was ist ein Closure?

Ein Closure bezeichnet den Mechanismus, durch den eine Funktion auf Variablen in ihrem Entstehungskontext zugreifen kann, selbst wenn sie außerhalb dieses Kontexts aufgerufen wird. Durch die Nutzung von Closures ist es möglich, dass Funktionen externe Variablen dauerhaft ‚merken‘.

Closures bestehen aus den folgenden zwei Elementen.

  1. Funktionsdefinition (die Funktion selbst)

  2. Gültigkeitsbereich, in dem die Funktion definiert wurde (Variablen und andere Funktionen außerhalb der Funktion selbst)

In JavaScript sind Closures möglich, weil Funktionen auf Variablen im Kontext ihres Entstehungsortes zugreifen können.

Grundlegendes Beispiel

Schauen wir uns zunächst ein grundlegendes Beispiel für ein Closure an. Im folgenden Code gibt outerFunction eine Funktion namens innerFunction zurück. Wichtig ist, dass innerFunction auf die innerhalb von outerFunction definierte Variable count zugreifen kann.

 1function outerFunction() {
 2    let count = 0;
 3
 4    function innerFunction() {
 5        count++;
 6        console.log(`Current count: ${count}`);
 7    }
 8
 9    return innerFunction;
10}
11
12const counter = outerFunction();
13counter(); // Current count: 1
14counter(); // Current count: 2
15counter(); // Current count: 3

Wie Closures funktionieren

Wie im obigen Beispiel zu sehen ist, bleibt count in innerFunction erhalten, selbst nachdem outerFunction ausgeführt wurde. innerFunction kann weiterhin auf den Gültigkeitsbereich von outerFunction zugreifen, und somit wird count innerhalb von innerFunction aktualisiert. Das ist das grundlegende Funktionsprinzip eines Closures.

innerFunction wird der Variable counter zugewiesen, und wir sehen, dass der Zustand von count erhalten bleibt, obwohl outerFunction bereits ausgeführt wurde. Das liegt daran, dass JavaScript sich den Gültigkeitsbereich zum Zeitpunkt der Funktionsdefinition dauerhaft ‚merkt‘.

Anwendung: Closures als private Variablen

Closures können ähnlich wie ‚private Variablen‘ in der objektorientierten Programmierung verwendet werden. Normalerweise sind in JavaScript Objekteigenschaften von außen direkt zugänglich, aber durch die Verwendung von Closures ist es möglich, die direkte Manipulation von Variablen im Funktionsbereich von außen zu verhindern.

Im nächsten Beispiel verwendet die Funktion createCounter ein Closure, um einen Zähler zu erstellen, und gibt einen Zähler mit einer privaten Variable count zurück.

 1function createCounter() {
 2    let count = 0;
 3
 4    return {
 5        increment: function() {
 6            count++;
 7            console.log(`Count: ${count}`);
 8        },
 9        decrement: function() {
10            count--;
11            console.log(`Count: ${count}`);
12        },
13        getCount: function() {
14            return count;
15        }
16    };
17}
18
19const myCounter = createCounter();
20myCounter.increment(); // Count: 1
21myCounter.increment(); // Count: 2
22myCounter.decrement(); // Count: 1
23console.log(myCounter.getCount()); // 1

In diesem Beispiel befindet sich count im Gültigkeitsbereich der Funktion createCounter und kann daher nicht direkt von außen zugegriffen werden. Sie kann jedoch über die Methoden increment und decrement verändert werden. Auf diese Weise können durch die Verwendung von Closures private Variablen in JavaScript realisiert werden.

Praktische Anwendungsbeispiele für Closures

Kombination mit Callback-Funktionen

Closures werden häufig zusammen mit Callback-Funktionen zur Verwaltung asynchroner Prozesse verwendet. Lass uns zum Beispiel einen Anwendungsfall mit einem Timer betrachten.

 1function startTimer(duration) {
 2    let timeLeft = duration;
 3
 4    function countdown() {
 5        console.log(`Time left: ${timeLeft} seconds`);
 6        timeLeft--;
 7
 8        if (timeLeft >= 0) {
 9            setTimeout(countdown, 1000);
10        }
11    }
12
13    countdown();
14}
15
16startTimer(5);
17// Time left: 5 seconds
18// Time left: 4 seconds
19// Time left: 3 seconds
20// Time left: 2 seconds
21// Time left: 1 second
22// Time left: 0 seconds

In diesem Beispiel greift die Funktion countdown auf die Variable timeLeft im Geltungsbereich von startTimer zu. Auf diese Weise sind Closures sehr nützlich für asynchrone Vorgänge wie Timer, da sie den Zustand von Variablen über die Zeit hinweg erhalten.

Ereignis-Handler

Closures sind auch beim Einrichten von Event-Handlern sehr praktisch. Im folgenden Beispiel wird ein Closure verwendet, um die Anzahl der Klicks auf einen Button zu speichern.

 1function setupClickCounter(buttonId) {
 2    let clickCount = 0;
 3
 4    const button = document.getElementById(buttonId);
 5    button.addEventListener('click', function() {
 6        clickCount++;
 7        console.log(`Button clicked ${clickCount} times`);
 8    });
 9}
10
11setupClickCounter('myButton');

In diesem Fall wird clickCount bei jedem Klick erhöht und der Wert bleibt erhalten. Durch Closures kann jedem Button ein unabhängiger Zähler zugewiesen werden.

Fazit

Closures sind ein Konzept, das die Flexibilität und Leistungsfähigkeit von JavaScript symbolisiert. Sie halten Variablen, die in einem Funktionsbereich eingeschlossen sind, und ermöglichen Operationen auf diese Variablen durch von außen zugängliche Funktionen. Durch das Verständnis und die Nutzung dieses Mechanismus kannst du fortgeschrittenere Fähigkeiten im JavaScript-Programmieren erwerben.

Closures finden in verschiedenen Situationen Anwendung, von Event-Handling und asynchroner Verarbeitung bis hin zu Pseudo-Implementierungen objektorientierter Programmierung.

Sie können den obigen Artikel mit Visual Studio Code auf unserem YouTube-Kanal verfolgen. Bitte schauen Sie sich auch den YouTube-Kanal an.

YouTube Video