JavaScript Closures und Scope verstehen | Enjyn Gruppe
Hallo Welt
→
→
Hallo Welt
Original Lingva Deutsch
Übersetzung wird vorbereitet...
Dieser Vorgang kann bis zu 60 Sekunden dauern.
Diese Seite wird erstmalig übersetzt und dann für alle Besucher gespeichert.
0%
DE Zurück zu Deutsch
Übersetzung durch Lingva Translate

330 Dokumentationen verfügbar

Wissensdatenbank

JavaScript Closures Scope

Zuletzt aktualisiert: 14.07.2026 um 12:29 Uhr

JavaScript Closures und Scope verstehen

Closures sind eines der mächtigsten Konzepte in JavaScript. Lernen Sie Scope-Regeln und praktische Closure-Patterns.

Scope-Arten in JavaScript

Scope Beschreibung Deklaration
Global Überall verfügbar Außerhalb von Funktionen
Function Nur in der Funktion var, function
Block Nur im Block {} let, const
Module Nur im Modul ES6 Modules

Lexical Scope

// JavaScript verwendet LEXICAL SCOPE (auch: Static Scope)
// Der Scope wird zur SCHREIBZEIT festgelegt, nicht zur Laufzeit

const global = 'Ich bin global';

function outer() {
    const outerVar = 'Ich bin in outer';

    function inner() {
        const innerVar = 'Ich bin in inner';

        // inner kann auf alles zugreifen:
        console.log(innerVar);   // ✅ eigener Scope
        console.log(outerVar);   // ✅ äußerer Scope (Closure!)
        console.log(global);     // ✅ globaler Scope
    }

    inner();
    // console.log(innerVar);  // ❌ ReferenceError
}

outer();
// console.log(outerVar);      // ❌ ReferenceError

Was ist eine Closure?

// Eine Closure entsteht, wenn eine Funktion auf Variablen
// aus ihrem äußeren Scope zugreift - auch nachdem die
// äußere Funktion bereits beendet ist!

function createCounter() {
    let count = 0;  // Diese Variable wird "eingeschlossen"

    return function() {
        count++;    // Zugriff auf count aus äußerem Scope
        return count;
    };
}

const counter = createCounter();
// createCounter() ist BEENDET, aber count lebt weiter!

console.log(counter());  // 1
console.log(counter());  // 2
console.log(counter());  // 3

// count ist von außen nicht zugänglich!
// console.log(count);  // ❌ ReferenceError

Closure für private Variablen

function createBankAccount(initialBalance) {
    let balance = initialBalance;  // Private Variable
    const transactions = [];       // Private Array

    return {
        deposit(amount) {
            if (amount > 0) {
                balance += amount;
                transactions.push({ type: 'deposit', amount });
                return balance;
            }
        },

        withdraw(amount) {
            if (amount > 0 && amount <= balance) {
                balance -= amount;
                transactions.push({ type: 'withdraw', amount });
                return balance;
            }
            return 'Nicht genug Guthaben';
        },

        getBalance() {
            return balance;  // Nur lesen, nicht direkt ändern
        },

        getTransactions() {
            return [...transactions];  // Kopie zurückgeben
        }
    };
}

const account = createBankAccount(100);
account.deposit(50);      // 150
account.withdraw(30);     // 120
account.getBalance();     // 120

// Direkt auf balance zugreifen? UNMÖGLICH!
// account.balance = 1000000;  // Erstellt nur neue Property
// account.getBalance();       // Immer noch 120

Das klassische Loop-Problem

// ❌ PROBLEM mit var
for (var i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i);  // Gibt 3, 3, 3 aus!
    }, 100);
}
// var ist function-scoped, nicht block-scoped
// Alle Callbacks referenzieren dasselbe i

// ✅ LÖSUNG 1: let verwenden
for (let i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i);  // Gibt 0, 1, 2 aus!
    }, 100);
}
// let ist block-scoped, jede Iteration hat eigenes i

// ✅ LÖSUNG 2: IIFE (Immediately Invoked Function Expression)
for (var i = 0; i < 3; i++) {
    (function(j) {
        setTimeout(() => {
            console.log(j);  // Gibt 0, 1, 2 aus!
        }, 100);
    })(i);  // i wird als j "eingefangen"
}

Praktische Closure-Patterns

// 1. MEMOIZATION - Ergebnisse cachen
function memoize(fn) {
    const cache = {};  // Closure über cache

    return function(...args) {
        const key = JSON.stringify(args);

        if (key in cache) {
            console.log('Aus Cache:', key);
            return cache[key];
        }

        const result = fn.apply(this, args);
        cache[key] = result;
        return result;
    };
}

const expensiveCalc = memoize((n) => {
    console.log('Berechne...');
    return n * n;
});

expensiveCalc(5);  // "Berechne..." → 25
expensiveCalc(5);  // "Aus Cache:" → 25 (keine Berechnung)
// 2. FUNCTION FACTORY
function createMultiplier(factor) {
    return function(number) {
        return number * factor;
    };
}

const double = createMultiplier(2);
const triple = createMultiplier(3);

double(5);  // 10
triple(5);  // 15
// 3. ONCE - Funktion nur einmal ausführen
function once(fn) {
    let called = false;
    let result;

    return function(...args) {
        if (!called) {
            called = true;
            result = fn.apply(this, args);
        }
        return result;
    };
}

const initialize = once(() => {
    console.log('Initialisierung...');
    return 'Fertig';
});

initialize();  // "Initialisierung..." → "Fertig"
initialize();  // → "Fertig" (keine erneute Ausführung)
// 4. DEBOUNCE - Verzögerte Ausführung
function debounce(fn, delay) {
    let timeoutId;

    return function(...args) {
        clearTimeout(timeoutId);

        timeoutId = setTimeout(() => {
            fn.apply(this, args);
        }, delay);
    };
}

const searchInput = debounce((query) => {
    console.log('Suche nach:', query);
    // API Call...
}, 300);

// Wird nur einmal ausgeführt (nach 300ms Pause)
searchInput('H');
searchInput('He');
searchInput('Hel');
searchInput('Hell');
searchInput('Hello');  // Nur dieser wird ausgeführt

Closure-Fallen vermeiden

// ❌ Memory Leak durch Closure
function createHandler() {
    const hugeData = new Array(1000000).fill('x');

    return function handler() {
        // hugeData wird nie freigegeben!
        console.log('Handler aufgerufen');
    };
}

// ✅ Besser: Nur benötigte Daten einschließen
function createHandler() {
    const hugeData = new Array(1000000).fill('x');
    const neededValue = hugeData.length;  // Nur das Nötige

    return function handler() {
        console.log('Länge:', neededValue);
    };
}
// ❌ Unbeabsichtigte Closure
function setupButtons() {
    for (var i = 0; i < buttons.length; i++) {
        buttons[i].onclick = function() {
            console.log('Button', i);  // Immer letzter Index!
        };
    }
}

// ✅ Richtig mit let oder bind
function setupButtons() {
    for (let i = 0; i < buttons.length; i++) {
        buttons[i].onclick = function() {
            console.log('Button', i);  // Korrekter Index
        };
    }
}
💡 Merke: Eine Closure ist eine Funktion plus ihre lexikalische Umgebung. Sie ermöglicht private Variablen, State-Management und viele nützliche Patterns. Achten Sie auf Memory Leaks bei großen eingeschlossenen Objekten!

Weitere Informationen

Texterstellung mit KI-Unterstützung

Enjix Beta

Enjyn AI Agent

Hallo 👋 Ich bin Enjix — wie kann ich dir helfen?
LLMs können Fehler machen. Ihre Nachrichten werden an Google Gemini weitergeleitet.
120