break verlässt eine Schleife oder ein switch-Statement vorzeitig. continue überspringt den Rest des aktuellen Durchlaufs und springt zur nächsten Iteration. Beide Statements wirken standardmäßig nur auf die innerste Schleife. Für äußere Schleifen gibt es Labels — eine wenig genutzte Syntax, die in seltenen Fällen aber genau das Richtige ist. Dieser Artikel zeigt die Grundformen, dokumentiert das Label-Feature und nennt die wenigen Stellen, an denen Labels einer Alternative überlegen sind.

break in Schleifen

break verlässt die Schleife sofort. Die Ausführung springt zur ersten Anweisung nach der Schleife.

JavaScript break-loop.js
function findeErsteGerade(arr) {
    for (const x of arr) {
        if (x % 2 === 0) {
            return x;   // alternativ: break + Variable
        }
    }
    return undefined;
}

console.log(findeErsteGerade([1, 3, 7, 4, 9])); // 4

// Klassisch mit break
const arr = [1, 3, 7, 4, 9];
let gefunden;
for (const x of arr) {
    if (x % 2 === 0) {
        gefunden = x;
        break;   // sofortiger Ausstieg
    }
}
console.log(gefunden); // 4
Output
4
4

In Funktionen ist meist return lesbarer als break mit Variable — keine Zwischen-Schritte, keine Variable außerhalb der Schleife. break ist relevant, wenn man die Schleife verlässt, aber nicht die ganze Funktion.

break in switch

break ist in switch der Standard-Terminator, um Fall-through zu verhindern. Detail-Behandlung im switch-Artikel.

JavaScript break-switch.js
function farbe(level) {
    let result;
    switch (level) {
        case 'info':  result = 'blue';   break;
        case 'warn':  result = 'orange'; break;
        case 'error': result = 'red';    break;
        default:      result = 'gray';
    }
    return result;
}

console.log(farbe('warn')); // 'orange'
Output
orange

continue — zur nächsten Iteration

continue überspringt den Rest des aktuellen Schleifen-Durchlaufs. In for springt es zum Update-Teil (i++ etc.), in while direkt zur Bedingung.

JavaScript continue-grundform.js
// Nur gerade Zahlen verarbeiten
for (let i = 0; i < 10; i++) {
    if (i % 2 !== 0) continue;
    console.log('gerade:', i);
}
Output
gerade: 0
gerade: 2
gerade: 4
gerade: 6
gerade: 8

continue ist eine Stil-Frage: manche Style-Guides bevorzugen die invertierte Form if (gerade) { ... } ohne continue, andere finden continue als Guard-Clause der Schleife klarer. Für lange Schleifen-Bodies mit mehreren Filter-Bedingungen sind frühe continue-Statements analog zu Early-Returns oft die Sieger.

Standardmäßig nur die innerste Schleife

Sowohl break als auch continue wirken nur auf die innerste umschließende Schleife.

JavaScript innerste-schleife.js
for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
        if (j === 1) break;   // bricht NUR die innere Schleife ab
        console.log(`i=${i}, j=${j}`);
    }
}
Output
i=0, j=0
i=1, j=0
i=2, j=0

Die äußere i-Schleife läuft normal weiter. Für „beide Schleifen verlassen" braucht es entweder ein Label, ein Flag, eine ausgelagerte Funktion mit return oder eine throw-Konstruktion (zu drastisch).

Labels — name: schleife

Eine Label-Definition ist ein Identifier gefolgt von Doppelpunkt, direkt vor einer Schleife oder einem Block. Mit break name; oder continue name; adressiert man dann genau dieses Label.

JavaScript labels-break.js
aussen: for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
        if (j === 1) break aussen;   // bricht BEIDE Schleifen
        console.log(`i=${i}, j=${j}`);
    }
}
Output
i=0, j=0

Das gleiche funktioniert mit continue: continue label springt in den Update-/Bedingungs-Teil der labelten Schleife.

JavaScript labels-continue.js
aussen: for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
        if (j === 1) continue aussen;  // nächstes i
        console.log(`i=${i}, j=${j}`);
    }
}
Output
i=0, j=0
i=1, j=0
i=2, j=0

Diese Form ist die einzige, in der continue label außerhalb der labelten Schleife semantisch Sinn ergibt: vom Inneren der inneren Schleife direkt in den nächsten Durchlauf der äußeren springen.

Labels auf Blöcken

Labels können auch Blöcke kennzeichnen — nicht nur Schleifen. Mit break label; lässt sich der Block dann „nach unten" verlassen.

JavaScript block-label.js
verarbeitung: {
    console.log('Start');

    if (true) break verarbeitung;  // verlässt den Block

    console.log('Nie erreicht');
}
console.log('Nach Block');
Output
Start
Nach Block

Das ist eine sehr seltene Form. Manche Codebasen nutzen sie als „strukturiertes goto" für komplexe Validierungs-Logik. In den meisten Fällen ist eine Funktion mit Early-Returns lesbarer.

Alternativen zu Labels

In modernen Codebasen sind Labels selten. Die häufigeren Wege, denselben Effekt zu erreichen:

JavaScript alternativen.js
// Variante 1: Funktion mit return
function suche(matrix, ziel) {
    for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[i].length; j++) {
            if (matrix[i][j] === ziel) return [i, j];
        }
    }
    return null;
}
console.log(suche([[1, 2], [3, 4]], 4)); // [1, 1]

// Variante 2: Flag
function sucheFlag(matrix, ziel) {
    let pos = null;
    outerSearch:
    for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[i].length; j++) {
            if (matrix[i][j] === ziel) {
                pos = [i, j];
                break outerSearch;
            }
        }
    }
    return pos;
}
console.log(sucheFlag([[1, 2], [3, 4]], 4));

// Variante 3: some / find — fertige Methoden
function sucheFunctional(matrix, ziel) {
    const i = matrix.findIndex(row => row.includes(ziel));
    if (i < 0) return null;
    return [i, matrix[i].indexOf(ziel)];
}
console.log(sucheFunctional([[1, 2], [3, 4]], 4));
Output
[ 1, 1 ]
[ 1, 1 ]
[ 1, 1 ]

Faustregel: Funktion mit return ist meist die sauberste Form. Labels sind das letzte Mittel, wenn die Funktion aus anderen Gründen nicht zerlegt werden soll.

Label-Konventionen

Labels sind keine Variablen — sie leben in einem eigenen Namensraum. Aber Style-Guides empfehlen klare Konvention:

  • Labels GROSSGESCHRIEBEN oder mit Suffix (_loop, _block) — visuell von Variablen unterscheidbar.
  • Nur direkt vor der Schleife/dem Block — kein Code dazwischen.
  • Niemals mit Variablen-Namen kollidieren — auch wenn die Sprache es erlauben würde.
JavaScript label-konvention.js
// Empfohlene Konvention
OUTER: for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
        if (i * j > 4) break OUTER;
        console.log(i, j);
    }
}
Output
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2

ESLint hat dazu die Regeln no-labels (Labels komplett verbieten) und no-extra-label (unnötige Labels). Viele Codebasen aktivieren no-labels als Default und erlauben sie nur per // eslint-disable-next-line.

break/continue funktioniert NICHT in forEach

arr.forEach(callback) ruft den Callback in einer eigenen Funktion auf. Innerhalb einer Funktion sind break und continue ungültig — SyntaxError.

JavaScript foreach-break-bug.js
[1, 2, 3].forEach(x => {
    if (x === 2) break;  // SyntaxError: Illegal break statement
    console.log(x);
});

Lösungsalternativen, wenn man Abbruch braucht:

  • for...of mit break — die idiomatische Wahl.
  • Array.prototype.some() — bricht ab, sobald der Callback truthy zurückgibt.
  • Array.prototype.every() — bricht ab, sobald der Callback falsy zurückgibt.
  • Array.prototype.find()/findIndex() — wenn man genau ein Element sucht.
JavaScript foreach-alternativen.js
// some als Abbruch-Mechanik
[1, 2, 3, 4].some(x => {
    console.log('verarbeite', x);
    return x === 2;   // true → some bricht ab
});
Output
verarbeite 1
verarbeite 2

some als Abbruch-Werkzeug ist syntaktisch ein bisschen schräg (der Boolean-Rückgabewert ist „eigentlich" der Treffer-Indikator, nicht ein „brich-jetzt-ab"-Signal). Lesbarer ist meist die for...of-Version.

Besonderheiten

Labels sind in JavaScript verfügbar, aber selten genutzt

Anders als goto in C ist die Label-Syntax in JavaScript auf break/continue beschränkt — kein freier Sprung. Daher sind sie strukturell sicher. Trotzdem sind sie in modernen Codebasen rar: meist gibt es eine lesbarere Alternative (Funktion mit return, Flag, Array-Methode).

continue mit Label springt in äußere Schleife, nicht raus

Wichtige Unterscheidung: break label verlässt die Schleife, continue label macht in der Schleife mit dem nächsten Durchlauf weiter. continue aussen in einer verschachtelten Schleife heißt also: innere Schleife komplett überspringen, nächstes i++ der äußeren Schleife.

break ohne Argument funktioniert nicht in Funktionen

break ohne Label sucht die nächste umschließende Schleife oder switch. Wenn die nächste umschließende Konstruktion eine Funktion ist (z.B. ein forEach-Callback), wirft das einen SyntaxError. Innerhalb von Callback-basierten Methoden gibt es kein break — nur return aus dem Callback, das aber lediglich diesen einen Durchlauf beendet.

Label-Namensraum ist eigen — keine Variablen-Kollision

Ein Label outer kollidiert nicht mit einer Variable namens outer. Das ist eine Spec-Eigenschaft (eigener „Label Set" pro Funktion). Trotzdem unschöner Stil — Labels in Großbuchstaben oder mit Suffix kennzeichnen, um Verwechslung mit Variablen visuell zu vermeiden.

Block-Label + break: strukturiertes 'früh raus'

verarbeitung: { ... break verarbeitung; ... } erlaubt es, einen Block-Body vorzeitig zu verlassen. Das ist eines der wenigen Konstrukte, die sich wie ein eingeschränktes goto anfühlen. Praktisch fast nie nötig — eine Funktion mit Early-Returns macht dasselbe lesbarer.

break in finally — unterdrückt Exception

Wenn ein break oder return innerhalb eines finally-Blocks ausgeführt wird, „verschluckt" das eine eventuell ausstehende Exception aus dem try-Block. Linter wie ESLint warnen mit no-unsafe-finally. In sauberem Code: kein Control-Flow-Statement in finally.

ESLint no-labels: viele Codebasen verbieten Labels komplett

Airbnb, StandardJS und mehrere große Open-Source-Projekte haben no-labels aktiviert. Begründung: in 99 % der Fälle gibt es eine lesbarere Alternative. Wenn du Labels nutzen willst, ist das Opt-in über // eslint-disable-next-line no-labels die akzeptierte Form.

break aus mehreren switch-Ebenen ist ungewöhnlich, aber möglich

Ein switch innerhalb eines switch (selten gesehen): das innere break verlässt nur den inneren switch. Wer das äußere meinen will, braucht ein Label am äußeren switch. Lesbarer ist meistens: inneren switch in eine Funktion auslagern.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Kontrollstrukturen

Zur Übersicht