JavaScript-Code ist eine Folge von Statements
Ein JavaScript-Programm ist eine Liste von Statements – also Anweisungen, die die Engine von oben nach unten abarbeitet. Eine Variable zu deklarieren ist ein Statement. Eine Funktion aufzurufen ist ein Statement. Ein if- oder for-Block ebenfalls. Die einzelnen Statements werden durch Semikolons voneinander getrennt.
Drei Anweisungen, drei Semikolons. Die Engine führt die erste aus, dann die zweite, dann die dritte. Ziemlich überschaubar.
Whitespace und Einrückung sind für den Parser bedeutungslos. Du könntest alle drei Anweisungen mit Semikolons getrennt in eine einzige Zeile packen – das Ergebnis wäre identisch. Wir rücken den Code nur für uns Menschen ein, nicht für die Engine.
Blöcke fassen Anweisungen zusammen
Geschweifte Klammern { } bilden einen Block – eine Gruppe von Anweisungen, die die Engine als Einheit behandelt. Blöcke begegnen dir überall: in Funktionsrümpfen, in if-Zweigen, in Schleifen.
Die beiden console.log-Aufrufe innerhalb der geschweiften Klammern bilden den Body des if. Beachte: Nach dem schließenden } steht kein Semikolon – Blöcke sind keine Anweisungen, die abgeschlossen werden müssen. Die gesamte if-Anweisung endet mit dem Ende des Blocks.
Das ist eine typische Stolperfalle für alle, die aus Sprachen kommen, in denen nach jedem } ein ; folgen muss. In JavaScript ist das bei einem eigenständigen Block oder einem Kontrollstrukturblock nicht der Fall.
Ausdrücke vs. Anweisungen
Eine Unterscheidung, die man früh verinnerlichen sollte: Ausdrücke (expressions) liefern einen Wert, Anweisungen (statements) führen etwas aus.
2 + 3ist ein Ausdruck. Er wird zu5ausgewertet.let x = 2 + 3;ist eine Anweisung. Sie deklariert eine Variable und weist ihr das Ergebnis eines Ausdrucks zu.console.log("hi")ist ein Ausdruck (ein Funktionsaufruf liefertundefinedzurück), aber sobald er allein auf einer Zeile mit Semikolon steht, wird daraus eine Ausdrucksanweisung (expression statement).
Meistens musst du dir darüber keine Gedanken machen. Relevant wird es erst, wenn du auf Arrow Functions, ternäre Ausdrücke oder Stellen triffst, an denen JavaScript einen Ausdruck erwartet, du aber ein Statement hinschreibst (oder umgekehrt).
Semikolon in JavaScript – ja oder nein?
Ehrliche Antwort vorweg: JavaScript hat ein Feature namens Automatic Semicolon Insertion (ASI), das an den meisten Zeilenumbrüchen automatisch die fehlenden Semikolons für dich einfügt. Deshalb läuft Code wie dieser ohne Probleme:
Kein Semikolon, kein Fehler. ASI schaut sich jeden Zeilenumbruch an und fragt: "Könnte das nächste Token das aktuelle Statement fortsetzen?" Wenn nicht, setzt es ein Semikolon ein.
Dank Automatic Semicolon Insertion haben sich in der Praxis zwei legitime Stile etabliert:
- Immer Semikolons setzen. Das machen die meisten Codebases, Tutorials und Style Guides.
- Keine Semikolons. Wird in manchen modernen Projekten verwendet (Standard Style, einige React-Codebases). Setzt auf ASI plus ein paar defensive Kniffe.
Beides funktioniert. Keiner der beiden Wege ist "falsch". Falsch ist nur Inkonsistenz — wer beide Stile innerhalb einer Datei mischt, macht Bugs schwerer auffindbar.
Wo ASI zur Falle wird
ASI trifft in etwa 99 % der Fälle die richtige Entscheidung. Das restliche 1 % betrifft Zeilen, die mit einem Token beginnen, das die vorherige Zeile fortsetzen könnte. Die üblichen Übeltäter sind [, (, `, +, - und /.
Schau dir das an:
Man würde erwarten, dass x und y die Werte tauschen. Tatsächlich fügt ASI aber vor [x, y] kein Semikolon ein, weil 10[x, y] syntaktisch gültig ist (Indexzugriff auf die Zahl 10). Der Parser liest also Zeile 2 und Zeile 3 als einen einzigen großen Ausdruck – das Ergebnis ist ein Laufzeitfehler oder wirrer Output.
Beheben lässt sich das entweder mit einem Semikolon am Ende von Zeile 2:
Alternativ kannst du im No-Semicolon-Stil ein einleitendes Semikolon an den Anfang der problematischen Zeile setzen:
Dieses führende ; ist der klassische Defensiv-Trick aus Codebases ohne Semikolons. Sieht erstmal komisch aus – ergibt aber Sinn, sobald man den Grund kennt.
Die return-Falle
Einen ASI-Fall solltest du dir unbedingt merken, weil er zu stillen Bugs führt: Wenn du direkt nach return einen Zeilenumbruch setzt, fügt ASI an dieser Stelle ein Semikolon ein – und die Funktion gibt undefined zurück:
Der Autor wollte hier eigentlich ein Objekt zurückgeben. Doch ASI hat das return am Zeilenende gesehen und die Anweisung kurzerhand dort beendet. Das Objektliteral landet so im toten Code und wird nie erreicht.
Die Lösung: Den Wert direkt in dieselbe Zeile wie das return schreiben:
Die gleiche Regel gilt für throw, break, continue und yield – zwischen dem Keyword und seinem Wert darf kein Zeilenumbruch stehen.
Eine einfache Faustregel, die funktioniert
Für den Einstieg ist dieser Weg am unkompliziertesten:
- Setze Semikolons konsequent am Ende jeder Anweisung.
- Kein Semikolon nach einer schließenden
}beiif,for,while, Funktionsdeklarationen oder Klassenrümpfen. - Semikolon nach
}bei Objektliteralen oder Funktions_ausdrücken_, die einer Variablen zugewiesen werden:const f = function() {};. - Nutze einen Formatter (Prettier oder ESLint mit passender Style-Regel) und vergiss das Thema. Der Formatter setzt automatisch durch, worauf sich dein Team geeinigt hat.
Diese Regel ist kein universelles Gesetz – es ist die Konvention, die dir in den meisten JavaScript-Codes begegnen wird. Halte dich daran, solange du keinen guten Grund hast, davon abzuweichen.
Groß- und Kleinschreibung bei Bezeichnern
Zwei kleine Regeln, die hier ebenfalls hingehören:
- JavaScript unterscheidet zwischen Groß- und Kleinschreibung.
userName,usernameundUserNamesind drei verschiedene Bezeichner. - Bezeichner dürfen Buchstaben, Ziffern,
_und$enthalten, aber nicht mit einer Ziffer beginnen. Reservierte Wörter wieclass,returnoderfunctionsind ebenfalls tabu.
Das $ ist zwar erlaubt, wird aber per Konvention meist für library-spezifische Dinge reserviert (jQuery hat es historisch genutzt, einige Template-Systeme tun das bis heute). Selbst greift man eher selten dazu.
Als Nächstes: Strict Mode
Modernes JavaScript läuft im Hintergrund in einer strikteren Variante der Sprache – dem sogenannten Strict Mode. Dieser macht aus ein paar nachlässigen Verhaltensweisen echte Fehler. ES Modules und Klassenrümpfe sind automatisch im Strict Mode, trotzdem lohnt sich ein Blick darauf, was sich dabei konkret ändert. Genau darum geht es auf der nächsten Seite.
Häufig gestellte Fragen
Braucht man in JavaScript überhaupt Semikolons?
Streng genommen nein – JavaScript hat die sogenannte Automatic Semicolon Insertion (ASI) und setzt die Semikolons an den meisten Zeilenumbrüchen selbst. In der Praxis schreiben die meisten Teams sie trotzdem explizit, weil ASI in ein paar Spezialfällen daneben greift – nämlich bei Zeilen, die mit [, (, `, +, - oder / beginnen. Am entspanntesten fährst du, wenn du dich für einen Stil entscheidest und ihn von einem Formatter wie Prettier durchsetzen lässt.
Was ist Automatic Semicolon Insertion (ASI) in JavaScript?
ASI ist die Regel, nach der JavaScript am Zeilenende ein fehlendes Semikolon einfügt, sobald das nächste Token das aktuelle Statement nicht sinnvoll fortsetzen könnte. Deshalb funktioniert let x = 1 auch ohne Semikolon. Problematisch wird's, wenn die nächste Zeile zufällig mit etwas beginnt, das die vorherige Zeile doch fortsetzen kann – zum Beispiel [ oder ( – denn dann klebt JavaScript die beiden Zeilen klammheimlich zusammen.
Wie sieht ein typisches JavaScript-Statement aus?
Ein Statement ist eine Anweisung – eine Variablendeklaration, ein Funktionsaufruf, ein if-Block oder eine Schleife. Getrennt werden Statements durch Semikolons (ob explizit geschrieben oder von ASI ergänzt). Mehrere Statements fasst man in { } zu Blöcken zusammen. Whitespace und Einrückung ignoriert der Parser komplett – die sind für uns Menschen da, nicht für die Engine.