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.
'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.
'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.
| Bereich | Sloppy Mode | Strict Mode |
|---|---|---|
| Zuweisung an undeklarierte Variable | erzeugt globale Variable | ReferenceError |
| Schreibe auf non-writable Property | scheitert stillschweigend | TypeError |
| Schreibe auf Getter-only Property | scheitert stillschweigend | TypeError |
delete auf Variable / nicht-config. | scheitert stillschweigend | SyntaxError / TypeError |
this in normaler Funktion | globalThis / Boxed Primitive | tatsächlicher Wert (oft undefined) |
arguments ↔ Parameter | aliased, ändern sich gemeinsam | entkoppelt |
eval-Scope | leakt Variablen in äußeren Scope | eigener, isolierter Scope |
with-Statement | erlaubt | SyntaxError |
Octal-Literale 0123 | erlaubt | SyntaxError |
| doppelte Parameter-Namen | erlaubt | SyntaxError |
Reserved Words let, static, … | normale Identifier | reserviert, SyntaxError als Variablen |
| Function-Decl. in Block | hochgehoben in äußeren Scope | nur 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.
// 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(); // ReferenceErrorAuch Schreib-Versuche auf nicht beschreibbare Properties — etwa Konstanten von eingebauten Objekten — werden zu TypeErrors, statt stillschweigend ignoriert zu werden.
'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 muss0o123(ES6-Form) genutzt werden. - Doppelte Parameter-Namen in Funktions-Signaturen.
evalundargumentsals Variablen- oder Parameter-Namen.
'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.
'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)undefined
2
null
trueKlassische 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.
'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.
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[ 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.
'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)17
42In 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,ViteundRollupproduzieren in der Regel ESM und damit strict-Code.
// KEIN 'use strict' nötig — diese Datei ist als ESM bereits strict.
export function setze() {
x = 5; // ReferenceError: x is not defined
}// 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.
- 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. - 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
0123auf0o123umstellen.
- Stufe 3 — Migration zu ESM: sobald die Codebasis strict-clean ist, lohnt der Schritt zu ES Modules.
"type": "module"setzen,require-Aufrufe schrittweise durchimportersetzen. Das"use strict"aus den Dateien verschwindet danach automatisch — es ist redundant.
# 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=moduleIn 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.