Der Strict Mode ist ein Mechanismus aus ES5 (2009), mit dem JavaScript mehrere historisch gewachsene Stolperfallen abschalten lässt. Wer ihn aktiviert, tauscht stilles Versagen gegen klare Errors, verbietet sich selbst veraltete Syntax und bekommt ein deterministischeres this-Verhalten. In modernem Code passiert das fast nie noch explizit: ES Modules und Class-Bodies sind seit der Spezifikation automatisch strict — "use strict" ist dort schlicht ein No-Op. Dieser Artikel zeigt, was sich genau ändert, wo der Modus heute herkommt und welche Fallen beim Umstieg von Sloppy-Code lauern.

Hintergrund: opt-in-Modus aus ES5

Vor ES5 gab es nur einen Modus, heute oft Sloppy Mode genannt. Dieser Modus enthält Verhalten, das aus Kompatibilitätsgründen mit Code aus den frühen 2000ern bewusst nachsichtig ist: Tippfehler bei Variablen werden zu globalen Variablen, Zuweisungen an unveränderliche Properties scheitern stillschweigend, this zeigt im freien Funktionsaufruf auf das globale Objekt. Mit ES5 (Dezember 2009) bekam JavaScript einen zweiten Modus, der diese Altlasten gezielt abstellt — den Strict Mode.

Aktiviert wird er durch eine spezielle Direktive: das String-Literal "use strict" als allererste Anweisung einer Datei oder einer Funktion. Die Sprache hat ein subtiles Detail eingebaut: Engines, die den Modus nicht kennen, sehen einfach einen unbenutzten String und ignorieren ihn — der gleiche Code läuft also überall, mit oder ohne Strict-Effekt.

JavaScript strict.js — Datei-Ebene
'use strict';

// ab hier ist die gesamte Datei im strict mode
function main() {
    // erbt strict
}

Aktivierung: Datei vs. Funktion

Strict Mode kennt zwei Geltungsbereiche, wenn er manuell gesetzt wird. Auf Datei-Ebene muss "use strict" die allererste Anweisung sein — Kommentare davor sind erlaubt, jede andere Anweisung deaktiviert die Direktive stillschweigend. Auf Funktions-Ebene wird die Direktive an den Anfang des Function-Bodies gesetzt; nur diese eine Funktion (und alle inneren Funktionen) laufen dann strict.

JavaScript datei-vs-funktion.js
'use strict'; // (1) Datei-Ebene — gesamte Datei strict

function fileLevel() {
    // automatisch strict, weil Datei strict ist
}

// ----- alternativ: nur eine Funktion -----

function nichtStrict() {
    // Sloppy
    x = 5; // legt globale Variable an
}

function strictFn() {
    'use strict'; // (2) Funktion-Ebene
    // y = 5; // ReferenceError
}

In modernem Code ist die Funktions-Variante praktisch ausgestorben: Wer ESM nutzt, ist sowieso strict, und in einem strict-Kontext ist die innere Direktive eine Tautologie.

Übersicht der Änderungen

Strict Mode greift an mehreren Stellen gleichzeitig in die Sprachsemantik ein. Die folgende Tabelle fasst die wichtigsten Verhaltens-Änderungen zusammen.

BereichSloppy ModeStrict Mode
Zuweisung an undeklarierte Variableerzeugt globale VariableReferenceError
Schreibe auf non-writable Propertyscheitert stillschweigendTypeError
Schreibe auf Getter-only Propertyscheitert stillschweigendTypeError
delete auf Variable / nicht-config.scheitert stillschweigendSyntaxError / TypeError
this in normaler FunktionglobalThis / Boxed Primitivetatsächlicher Wert (oft undefined)
arguments ↔ Parameteraliased, ändern sich gemeinsamentkoppelt
eval-Scopeleakt Variablen in äußeren Scopeeigener, isolierter Scope
with-StatementerlaubtSyntaxError
Octal-Literale 0123erlaubtSyntaxError
doppelte Parameter-NamenerlaubtSyntaxError
Reserved Words let, static, …normale Identifierreserviert, SyntaxError als Variablen
Function-Decl. in Blockhochgehoben in äußeren Scopenur block-lokal sichtbar

Die nächsten Abschnitte zeigen die wichtigsten Punkte mit Code-Demos.

Stille Fehler werden zu Errors

Die ursprüngliche Motivation für Strict Mode: viele Stolperfallen aus dem Sloppy Mode scheitern still, statt eine klare Diagnose zu liefern. Strict Mode dreht das um.

JavaScript undeklarierte-variable.js
// Sloppy:  x = 5  legt heimlich window.x = 5 an
// Strict:  x = 5  -> ReferenceError: x is not defined

'use strict';

function setze() {
    x = 5; // Tippfehler? Ohne Strict ein globaler Leak.
}

setze(); // ReferenceError

Auch Schreib-Versuche auf nicht beschreibbare Properties — etwa Konstanten von eingebauten Objekten — werden zu TypeErrors, statt stillschweigend ignoriert zu werden.

JavaScript non-writable.js
'use strict';

undefined = 5;        // TypeError
Infinity  = 5;        // TypeError

const obj = {};
Object.defineProperty(obj, 'x', { value: 42, writable: false });
obj.x = 9;            // TypeError

const frozen = Object.freeze({ a: 1 });
frozen.a = 2;         // TypeError (sloppy: einfach ignoriert)

Verbotene Syntax

Strict Mode entfernt einige Sprach-Features komplett. Die wichtigsten:

  • with-Statements — galten schon vor 2010 als problematisch, weil sie die statische Auflösung von Bezeichnern unmöglich machen.
  • Legacy-Octal-Literale wie 0123. Statt dessen muss 0o123 (ES6-Form) genutzt werden.
  • Doppelte Parameter-Namen in Funktions-Signaturen.
  • eval und arguments als Variablen- oder Parameter-Namen.
JavaScript verbotene-syntax.js
'use strict';

// 1) with: SyntaxError
// with (Math) { console.log(PI); }

// 2) Octal: SyntaxError
// const n = 0123;
const ok = 0o123; // erlaubt

// 3) doppelte Parameter: SyntaxError
// function sum(a, a, c) { return a + a + c; }

// 4) eval / arguments als Identifier: SyntaxError
// const eval = 1;
// function f(arguments) {}

Diese Restriktionen wirken auf den ersten Blick willkürlich, sind aber das Fundament dafür, dass moderne Engines aggressiv optimieren können — und sie verhindern reale Bugs.

this in normalen Funktionen

Im Sloppy Mode wird ein freier Funktions-Aufruf — also ohne Receiver — so behandelt, als wäre this das globale Objekt (globalThis im Browser, global in Node-CommonJS). In Strict Mode bleibt this exakt das, was der Aufruf liefert: häufig undefined. Wird ein primitiver Wert via call/apply gebunden, findet im Sloppy Mode außerdem Auto-Boxing statt — (2).toString() macht aus der 2 ein Number-Objekt. Strict bewahrt den primitiven Wert.

JavaScript this-binding.js
'use strict';

function whoIsThis() {
    return this;
}

console.log(whoIsThis());            // undefined  (sloppy: globalThis)
console.log(whoIsThis.call(2));      // 2          (sloppy: Number-Objekt)
console.log(whoIsThis.apply(null));  // null       (sloppy: globalThis)
console.log(whoIsThis.bind(true)()); // true       (sloppy: Boolean-Objekt)
Output
undefined
2
null
true

Klassische Bug-Quelle: Method-Detach. Wer eine Methode aus einem Objekt heraus per Variable referenziert, verliert den Receiver — in Strict Mode meldet sich das mit einem klaren Fehler, in Sloppy Mode greift unbemerkt das globale Objekt.

JavaScript method-detach.js
'use strict';

const counter = {
    value: 0,
    inc() { this.value++; }
};

const inc = counter.inc; // Method-Detach
inc();                   // TypeError: Cannot read properties of undefined
                         // (sloppy: würde versuchen, globalThis.value zu erhöhen)

Das arguments-Objekt

Im Sloppy Mode sind arguments[i] und der entsprechende Named Parameter live verbunden: eine Änderung an einer Seite zieht die andere automatisch mit. Strict Mode entkoppelt beide — das Verhalten ist berechenbarer und entspricht dem mentalen Modell der meisten Entwickler.

JavaScript arguments-aliasing.js
function sloppy(a) {
    // ohne 'use strict' — Aliasing aktiv
    a = 42;
    return [a, arguments[0]];
}

function strict(a) {
    'use strict';
    a = 42;
    return [a, arguments[0]];
}

console.log(sloppy(17)); // [42, 42]   <- gemeinsam aktualisiert
console.log(strict(17)); // [42, 17]   <- entkoppelt
Output
[ 42, 42 ]
[ 42, 17 ]

Ergänzend werden in Strict Mode die historischen Stack-Walking-Properties arguments.callee und function.caller zu TypeError. Beide waren bereits vor Jahren als problematisch markiert, weil sie Closures, Tail-Call-Optimierung und sichere Iframes torpedieren.

eval bekommt einen eigenen Scope

In Sloppy Mode kann eval neue Variablen direkt in den umliegenden Scope einführen — ein Albtraum für statische Analyse und ein Performance-Killer für Optimierer. Strict Mode legt für eval einen eigenen, gekapselten Scope an: was dort deklariert wird, bleibt drin.

JavaScript eval-scope.js
'use strict';

var x = 17;
var evalX = eval("'use strict'; var x = 42; x;");

console.log(x);     // 17  (außen unverändert)
console.log(evalX); // 42  (innerhalb von eval erzeugt)
Output
17
42

In modernem Code sollte eval ohnehin nicht vorkommen; aber falls es doch nötig wird, ist die Strict-Variante die einzig sinnvolle.

Modern: ESM und Class-Bodies sind automatisch strict

Wer 2026 neuen Code schreibt, arbeitet fast immer in einem Kontext, in dem Strict Mode bereits aktiv ist — ohne dass "use strict" in der Datei stehen muss.

  • ES Modules: jede .mjs-Datei und jede .js-Datei in einem Paket mit "type": "module" ist laut Spezifikation strict.
  • Class-Bodies: alles zwischen class C { ... } läuft strict, auch wenn die umgebende Datei sloppy ist.
  • Bundler-Output: esbuild, Vite und Rollup produzieren in der Regel ESM und damit strict-Code.
JavaScript esm.mjs (automatisch strict)
// KEIN 'use strict' nötig — diese Datei ist als ESM bereits strict.

export function setze() {
    x = 5; // ReferenceError: x is not defined
}
JavaScript class-body-strict.js
// umgebende Datei kann sloppy sein
class Counter {
    // ab hier strict — automatisch
    #value = 0;
    inc() {
        this.#value++; // funktioniert
        // y = 1; // ReferenceError
    }
}

Bestand-Code in Strict Mode portieren

Eine Sloppy-Codebasis auf Strict umzustellen ist oft weniger Aufwand als befürchtet — man muss aber methodisch vorgehen.

  1. Stufe 1 — Datei-Direktiven setzen: "use strict" als erste Zeile in jede Datei. Tests laufen lassen. Die meisten verbleibenden Probleme zeigen sich jetzt als Errors.
  2. Stufe 2 — typische Patterns abklopfen:
    • this-Aufrufe ohne Receiver — Methoden, die als Callback weitergereicht werden.
    • Versehentliche globale Variablen (Tippfehler bei Zuweisungen).
    • delete x; auf einer Variable — durch sauberes Re-Assign ersetzen.
    • Octal-Literale 0123 auf 0o123 umstellen.
  3. Stufe 3 — Migration zu ESM: sobald die Codebasis strict-clean ist, lohnt der Schritt zu ES Modules. "type": "module" setzen, require-Aufrufe schrittweise durch import ersetzen. Das "use strict" aus den Dateien verschwindet danach automatisch — es ist redundant.
Bash Migrationsschritte (Skizze)
# 1. Strict-Direktive in alle src/-Dateien einfügen (manuell oder per Script)
# 2. Tests laufen lassen
npm test

# 3. Häufige Fehlermuster suchen
grep -rn "function .* {$" src/ | head    # Methoden ohne 'this' prüfen
grep -rn "= 0[0-9]" src/                  # Octal-Literale aufspüren

# 4. ESM aktivieren (sobald strict-clean)
npm pkg set type=module

In der Praxis ist die Mischung üblich: einzelne Legacy-Module bleiben als CommonJS bestehen, neuer Code entsteht direkt in ESM und damit immer strict. Beides koexistiert in Node ohne Reibung.

Typische Fallen

'use strict' muss die ALLERERSTE Anweisung sein

Kommentare davor sind okay, aber jede andere Anweisung deaktiviert die Direktive stillschweigend. Klassische Falle: ein automatisch generierter Header-Block (Banner, Lizenz-Hinweis als Statement, Polyfill-Loader) steht oben und macht "use strict" wirkungslos. Dann läuft die Datei plötzlich doch sloppy — ohne Warnung.

In Class-Bodies und ESM ist 'use strict' ein No-Op

Die Direktive in einer ESM-Datei oder innerhalb einer Class ist nicht falsch — sie ist nur überflüssig. Linter wie ESLint melden das mit der Regel strict: 'never' für Module. Sauberer Code lässt sie weg.

Sloppy Mode existiert nur noch für Backward-Compatibility

Die Spezifikation hält Sloppy am Leben, damit alte Webseiten weiter funktionieren. Neuer Code sollte aber kompromisslos in einem strict-Kontext laufen — also als ESM oder innerhalb einer Class. Sloppy-Code ist 2026 ein Zeichen für Tech-Debt.

Bundler erzwingen meist strict — auch ohne Direktive

esbuild, Vite und webpack produzieren in modernen Configs ESM-Output. Selbst wenn der Source-Code keine "use strict"-Direktive trägt, ist das Bundle am Ende strict. Wer im Source darauf verzichtet hat, sieht Strict-Effekte erst im gebauten Artefakt — Debugging in Source-Maps wird dadurch leicht verwirrend.

Method-Detach bricht in strict mit klarem TypeError

const log = console.log; log('x'); funktioniert in console-Implementierungen meist trotzdem (intern abgesichert), aber bei eigenen Klassen ist das ein häufiger Bug. Strict liefert hier sofort einen TypeError, sloppy liefert kryptisches Fehlverhalten. Die Lösung ist Method-Binding: const inc = counter.inc.bind(counter).

delete auf Variablen wirft in strict einen SyntaxError

var x; delete x; ist in sloppy schlicht ein No-Op, in strict ein SyntaxError beim Parsen. Auch delete auf non-configurable Properties (z. B. Object.freeze-Resultate) wirft TypeError, statt stillschweigend zu scheitern. In modernem Code sollte delete ohnehin nur auf eigene Object-Properties angewandt werden.

Doppelte Parameter-Namen sind ein Parser-Fehler

function f(a, a) { ... } bricht den Parser im strict mode. Tritt selten direkt auf, aber bei generierten Wrapper-Funktionen (Currying, Partial Application via String-Concat) kann es passieren — und der Fehler erscheint dann an unerwarteter Stelle.

Octal-Literale 0123 sind verboten — 0o123 ersetzen

Legacy-Octals waren immer ein Sonderling, weil 010 als 8 interpretiert wurde — eine klassische Falle bei Stunden-/Minuten-Arithmetik. Strict mode fordert die ES6-Form 0o10; Codebasen mit numerischen Konstanten aus alten Quellen sollten das beim Migrations-Schritt mit prüfen.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Grundlagen

Zur Übersicht