| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Strict_mode | [Back] [Original] |
Get to know MDN better
Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.
Hinweis: Manchmal wird der Standard-Non-Strict-Modus als sloppy mode bezeichnet. Dies ist kein offizieller Begriff, aber seien Sie sich dessen bewusst, nur fr den Fall.
Der Strict-Modus von JavaScript ist eine Mglichkeit, sich fr eine eingeschrnkte Variante von JavaScript zu entscheiden und dabei implizit aus dem "sloppy mode" auszusteigen. Der Strict-Modus ist nicht nur ein Subset: Er hat absichtlich andere Semantiken als normaler Code. Strict-Modus-Code und Non-Strict-Modus-Code knnen koexistieren, sodass Skripte schrittweise in den Strict-Modus wechseln knnen.
Der Strict-Modus fhrt mehrere nderungen an den normalen JavaScript-Semantiken durch:
Der Strict-Modus gilt fr komplette Skripte oder fr einzelne Funktionen. Er gilt nicht fr Blockanweisungen, die in {}-Klammern eingeschlossen sind; der Versuch, ihn in solchen Kontexten anzuwenden, hat keine Wirkung. eval-Code, Function-Code, Ereignishandler--Attribute, Zeichenketten, die an setTimeout() und verwandte Funktionen bergeben werden, sind entweder Funktionskrper oder komplette Skripte, und der Strict-Modus in ihnen wird wie erwartet aktiviert.
Um den Strict-Modus fr ein komplettes Skript zu aktivieren, setzen Sie die exakte Anweisung "use strict"; (oder 'use strict';) vor alle anderen Anweisungen.
// Whole-script strict mode syntax
"use strict";
const v = "Hi! I'm a strict mode script!";
Ebenso setzt man die exakte Anweisung "use strict"; (oder 'use strict';) in den Funktionskrper vor alle anderen Anweisungen, um den Strict-Modus fr eine Funktion zu aktivieren.
function myStrictFunction() {
// Function-level strict mode syntax
"use strict";
function nested() {
return "And so am I!";
}
return `Hi! I'm a strict mode function! ${nested()}`;
}
function myNotStrictFunction() {
return "I'm not strict.";
}
Die "use strict"-Direktive kann nur auf den Krper von Funktionen mit einfachen Parametern angewendet werden. Die Verwendung von "use strict" in Funktionen mit Rest-, Standard- oder destrukturierten Parametern ist ein Syntaxfehler.
function sum(a = 1, b = 2) {
// SyntaxError: "use strict" not allowed in function with default parameter
"use strict";
return a + b;
}
Der gesamte Inhalt von JavaScript-Modulen befindet sich automatisch im Strict-Modus, ohne dass eine Anweisung zur Initiierung erforderlich ist.
function myStrictFunction() {
// because this is a module, I'm strict by default
}
export default myStrictFunction;
Alle Teile des Krpers einer Klasse sind Strict-Modus-Code, einschlielich sowohl Klassen-Deklarationen als auch Klassen-Ausdrcke.
class C1 {
// All code here is evaluated in strict mode
test() {
delete Object.prototype;
}
}
new C1().test(); // TypeError, because test() is in strict mode
const C2 = class {
// All code here is evaluated in strict mode
};
// Code here may not be in strict mode
delete Object.prototype; // Will not throw error
Der Strict-Modus ndert sowohl die Syntax als auch das Laufzeitverhalten. Die nderungen fallen im Allgemeinen in folgende Kategorien:
eval und arguments vereinfachenDer Strict-Modus wandelt einige zuvor akzeptierte Fehler in tatschliche Fehler um. JavaScript wurde so konzipiert, dass es fr Anfnger leicht zugnglich ist, weshalb es manchmal Operationen zulsst, die eigentlich Fehler sein sollten, und stattdessen keine Fehler-Semantik verwendet. Manchmal lst dies das unmittelbare Problem, aber manchmal fhrt dies in der Zukunft zu schlimmeren Problemen. Der Strict-Modus behandelt diese Fehler als Fehler, sodass sie entdeckt und sofort behoben werden.
Der Strict-Modus macht es unmglich, versehentlich globale Variablen zu erstellen. Im Sloppy-Modus erzeugt das falsche Schreiben einer Variablen in einer Zuweisung eine neue Eigenschaft im globalen Objekt und "funktioniert" weiterhin. Zuweisungen, die versehentlich globale Variablen erstellen wrden, werfen im Strict-Modus einen Fehler:
"use strict";
let mistypeVariable;
// Assuming no global variable mistypeVarible exists
// this line throws a ReferenceError due to the
// misspelling of "mistypeVariable" (lack of an "a")
mistypeVarible = 17;
Im Strict-Modus werfen bestimmte Zuweisungen Fehler, anstatt still zu scheitern. Es gibt drei Mglichkeiten, wie eine Eigenschaftszuweisung scheitern kann:
Zum Beispiel ist NaN eine nicht-schreibbare globale Variable. Im Sloppy-Modus tut die Zuweisung zu NaN nichts; der Entwickler erhlt kein Feedback ber das Scheitern. Im Strict-Modus wirft die Zuweisung zu NaN eine Ausnahme.
"use strict";
// Assignment to a non-writable global
undefined = 5; // TypeError
Infinity = 5; // TypeError
// Assignment to a non-writable property
const obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // TypeError
// Assignment to a getter-only property
const obj2 = {
get x() {
return 17;
},
};
obj2.x = 5; // TypeError
// Assignment to a new property on a non-extensible object
const fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // TypeError
Versuche, eine nicht-konfigurierbare oder anderweitig nicht lschbare (z. B. wird sie von einem Proxy abgefangen, dessen deleteProperty-Handler false zurckgibt) Eigenschaft zu lschen, werfen im Strict-Modus einen Fehler (wo der Versuch vorher keinen Effekt hatte):
"use strict";
delete Object.prototype; // TypeError
delete [].length; // TypeError
Der Strict-Modus verbietet auch das Lschen von einfachen Namen. delete name ist im Strict-Modus ein Syntaxfehler:
"use strict";
var x;
delete x; // syntax error
Wenn der Name eine konfigurierbare globale Eigenschaft ist, prfixieren Sie ihn mit globalThis, um ihn zu lschen.
"use strict";
delete globalThis.x;
Der Strict-Modus fordert, dass Funktionsparameter-Namen eindeutig sind. Im Sloppy-Modus verbirgt das letzte doppelte Argument vorherige gleichnamige Argumente. Diese vorherigen Argumente sind ber arguments(/de/docs/Web/JavaScript/Reference/Functions/arguments) weiterhin zugnglich und nicht vollstndig unzugnglich. Dennoch ergibt dieses Verbergen wenig Sinn und ist wahrscheinlich unerwnscht (es knnte z. B. einen Tippfehler verbergen), daher ist es im Strict-Modus ein Syntaxfehler, doppelte Argumentnamen zu haben:
function sum(a, a, c) {
// syntax error
"use strict";
return a + a + c; // wrong if this code ran
}
Es ist auch im Non-Strict-Modus ein Syntaxfehler, doppelte Parameternamen zu haben, wenn die Funktion einen Standardparameter, Rest-Parameter oder destruierte Parameter hat.
Der Strict-Modus verbot ein 0-prfixiertes Oktalliteral. Im Sloppy-Modus wird eine Zahl, die mit einer 0 beginnt, wie 0644, als Oktalzahl interpretiert (0644 === 420), wenn alle Ziffern kleiner als 8 sind. Anfnger glauben manchmal, dass ein Vorzeichen der Null keine semantische Bedeutung hat, sodass sie es als Ausrichtungsgert verwenden knnten - aber dies ndert die Bedeutung der Zahl! Eine Vorzeichen-Null-Syntax fr das Oktal ist selten ntzlich und kann versehentlich verwendet werden, daher macht der Strict-Modus dies zu einem Syntaxfehler:
"use strict";
const sum =
015 + // syntax error
197 +
142;
Der standardisierte Weg, Oktalliterale zu kennzeichnen, ist das 0o-Prfix. Zum Beispiel:
const sumWithOctal = 0o10 + 8;
console.log(sumWithOctal); // 16
Oktale Escape-Sequenzen, wie "\45", die dem "%" entsprechen, knnen verwendet werden, um Zeichen durch erweiterte-ASCII-Zeichen-Code-Nummern im Oktal darzustellen. Im Strict-Modus ist dies ein Syntaxfehler. Formaler ist es nicht erlaubt, \ gefolgt von einer Dezimalziffer, die nicht 0 ist, oder \0 gefolgt von einer Dezimalziffer zu haben; zum Beispiel \9 und \07.
Der Strict-Modus verbietet das Setzen von Eigenschaften auf primitive Werte. Das Zugreifen auf eine Eigenschaft auf einem primitiven Wert erzeugt implizit ein Wrapper-Objekt, das nicht beobachtbar ist, so dass das Setzen von Eigenschaften im Sloppy-Modus ignoriert wird (keine Operation). Im Strict-Modus wird ein TypeError ausgelst.
"use strict";
false.true = ""; // TypeError
(14).sailing = "home"; // TypeError
"with".you = "far away"; // TypeError
Doppelte Eigenschaftsnamen wurden einst als SyntaxError im Strict-Modus betrachtet. Mit der Einfhrung von berechneten Eigenschaftsnamen, die eine Duplizierung zur Laufzeit ermglichen, wurde diese Einschrnkung in ES2015 aufgehoben.
"use strict";
const o = { p: 1, p: 2 }; // syntax error prior to ECMAScript 2015
Hinweis: Code, der frher Fehler verursacht hat, nicht mehr als Fehler zu behandeln, wird immer als rckwrtskompatibel betrachtet. Dies ist ein guter Teil der Sprache, die strikt in Bezug auf das Werfen von Fehlern ist: Es schafft Raum fr zuknftige semantische nderungen.
Der Strict-Modus vereinfacht, wie Variablennamen bestimmten Variablendefinitionen im Code zugewiesen werden. Viele Compiler-Optimierungen beruhen darauf, dass sie sagen knnen, dass die Variable X an diesem Ort gespeichert ist: Dies ist entscheidend fr die vollstndige Optimierung von JavaScript-Code. JavaScript macht manchmal diese grundlegende Zuordnung von Namen zu Variablendefinitionen im Code bis zur Laufzeit unmglich. Der Strict-Modus entfernt die meisten Flle, in denen dies passiert, sodass der Compiler den Strict-Modus-Code besser optimieren kann.
Der Strict-Modus verbietet with. Das Problem mit with ist, dass jeder Name innerhalb des Blocks entweder auf eine Eigenschaft des bergebenen Objekts oder auf eine Variable in umgebenden (oder sogar globalen) Scope zur Laufzeit abgebildet werden knnte; es ist vorher nicht mglich zu wissen, welches. Der Strict-Modus macht with zu einem Syntaxfehler, sodass es keine Chance gibt, dass ein Name in einem with zur Laufzeit auf einen unbekannten Ort verweist:
"use strict";
const x = 17;
with (obj) {
// Syntax error
// If this weren't strict mode, would this be const x, or
// would it instead be obj.x? It's impossible in general
// to say without running the code, so the name can't be
// optimized.
x;
}
Die Alternative, das Objekt einer kurzen Namenvariable zuzuweisen und die entsprechende Eigenschaft auf dieser Variablen zuzugreifen, steht bereit, with zu ersetzen.
Im Strict-Modus fgt `eval` keine neuen Variablen in den umgebenden Scope ein. Im Sloppy-Modus fhrt eval("var x;") eine Variable x in die umgebende Funktion oder den globalen Scope ein. Dies bedeutet, dass in einer Funktion, die einen Aufruf zu eval enthlt, im Allgemeinen jeder Name, der sich nicht auf ein Argument oder eine lokale Variable bezieht, zur Laufzeit einer bestimmten Definition zugeordnet werden muss (weil dieses eval eine neue Variable eingefhrt haben knnte, die die uere Variable verbergen wrde). Im Strict-Modus erstellt eval nur Variablen fr den Code, der ausgewertet wird, sodass eval nicht beeinflusst, ob ein Name auf eine uere Variable oder eine lokale Variable verweist:
var x = 17;
var evalX = eval("'use strict'; var x = 42; x;");
console.assert(x === 17);
console.assert(evalX === 42);
Ob die Zeichenfolge, die an eval() bergeben wird, im Strict-Modus ausgewertet wird, hngt davon ab, wie eval() aufgerufen wird (direktes eval oder indirektes eval).
Die JavaScript-Sprachspezifikation hatte seit ihrem Beginn keine Funktionsdeklarationen zugelassen, die in Block-Anweisungen verschachtelt sind. Es war jedoch so intuitiv, dass die meisten Browser es als Erweiterungsgrammatik implementierten. Leider divergierten die Semantiken der Implementierungen, und es wurde unmglich, dass die Sprachspezifikation alle Implementierungen in Einklang bringt. Daher sind Block-scope-Funktionsdeklarationen nur explizit im Strict-Modus spezifiziert (whrend sie im Strict-Modus frher nicht erlaubt waren), whrend das Sloppy-Modus-Verhalten weiterhin unter den Browsern divergent bleibt.
Der Strict-Modus macht arguments und eval weniger bizarr magisch. Beide beinhalten im Sloppy-Modus eine betrchtliche Menge an magischem Verhalten: eval, um Bindungen hinzuzufgen oder zu entfernen und Bindungswerte zu ndern, und arguments, zur Synchronisierung benannter Argumente mit seinen indizierten Eigenschaften. Der Strict-Modus unternimmt groe Schritte hin zur Behandlung von eval und arguments als Schlsselwrter.
Die Namen eval und arguments knnen in der Sprachsyntax nicht gebunden oder zugewiesen werden. Alle Versuche in dieser Richtung sind Syntaxfehler:
"use strict";
eval = 17;
arguments++;
++eval;
const obj = { set p(arguments) {} };
let eval;
try {
} catch (arguments) {}
function x(eval) {}
function arguments() {}
const y = function eval() {};
const f = new Function("arguments", "'use strict'; return 17;");
Der Strict-Modus-Code synchronisiert nicht die Indizes des arguments-Objekts mit jeder Parameterbindung. In einer Sloppy-Modus-Funktion, deren erstes Argument arg ist, setzt arg auch arguments[0], und umgekehrt (es sei denn, keine Argumente wurden bereitgestellt oder arguments[0] wurde gelscht). arguments-Objekte fr Funktionen im Strict-Modus speichern die ursprnglichen Argumente, wenn die Funktion aufgerufen wurde. arguments[i] verfolgt nicht den Wert des entsprechenden benannten Arguments, noch verfolgt ein benanntes Argument den Wert im entsprechenden arguments[i].
function f(a) {
"use strict";
a = 42;
return [a, arguments[0]];
}
const pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
Der Strict-Modus macht es einfacher, "sicheres" JavaScript zu schreiben. Einige Webseiten bieten jetzt Mglichkeiten an, wie Benutzer JavaScript schreiben knnen, das von der Webseite im Namen anderer Benutzer ausgefhrt wird. JavaScript in Browsern kann auf die privaten Informationen des Benutzers zugreifen, daher muss solches JavaScript teilweise transformiert werden, bevor es ausgefhrt wird, um den Zugriff auf verbotene Funktionalitten zu zensieren. JavaScripts Flexibilitt macht es effektiv unmglich, dies ohne viele Laufzeitprfungen zu tun. Bestimmte Sprachfunktionen sind so allgegenwrtig, dass das Durchfhren von Laufzeitprfungen erhebliche Leistungskosten hat. Einige Strict-Modus-nderungen, gepaart mit der Anforderung, dass benutzereingereichtes JavaScript Strict-Modus-Code sein muss und dass es in einer bestimmten Weise aufgerufen wird, reduziert den Bedarf an diesen Laufzeitprfungen erheblich.
this-SubstitutionDer im Strict-Modus an eine Funktion bergebene this-Wert wird nicht dazu gezwungen, ein Objekt zu sein (sogenanntes "Boxen"). Fr eine Sloppy-Modus-Funktion ist this immer ein Objekt: entweder das bereitgestellte Objekt, wenn es mit einem objektwertigen this aufgerufen wird; oder der "geboxte" Wert von this, wenn es mit einem primitiven Wert als this aufgerufen wird; oder das globale Objekt, wenn es mit undefined oder null als this aufgerufen wird. (Verwenden Sie call, apply oder bind, um einen bestimmten this anzugeben.) Nicht nur ist das automatische Boxen ein Leistungskostenfaktor, sondern das Offenlegen des globalen Objekts in Browsern stellt eine Sicherheitsgefhrdung dar, da das globale Objekt Zugriff auf Funktionalitten bietet, die "sichere" JavaScript-Umgebungen einschrnken mssen. Daher wird fr eine Funktion im Strict-Modus das angegebene this nicht in ein Objekt geboxet, und wenn nicht angegeben wird this stattdessen undefined anstelle von globalThis:
"use strict";
function fun() {
return this;
}
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);
Im Strict-Modus ist es nicht mehr mglich, den JavaScript-Stack zu "durchlaufen". Viele Implementierungen implementierten frher einige Erweiterungsfunktionen, die es ermglichen, den stromaufwrts liegenden Aufrufer einer Funktion zu erkennen. Wenn eine Funktion fun gerade aufgerufen wird, ist fun.caller die Funktion, die fun zuletzt aufgerufen hat, und fun.arguments ist das arguments fr diese Ausfhrung von fun. Beide Erweiterungen sind problematisch fr sicheres JavaScript, da sie es ermglichen, dass "gesicherter" Code auf "privilegierte" Funktionen und deren (mglicherweise ungesicherte) Argumente zugreifen kann. Wenn fun im Strict-Modus ist, sind sowohl fun.caller als auch fun.arguments nicht lschbare Eigenschaften, die beim Setzen oder Abrufen einen Fehler werfen.
function restricted() {
"use strict";
restricted.caller; // throws a TypeError
restricted.arguments; // throws a TypeError
}
function privilegedInvoker() {
return restricted();
}
privilegedInvoker();
Ebenso wird arguments.callee nicht mehr untersttzt. Im Sloppy-Modus bezieht sich arguments.callee auf die umschlieende Funktion. Dieser Anwendungsfall ist schwach: Benennen Sie die umschlieende Funktion! Darber hinaus behindert arguments.callee erheblich Optimierungen wie das Inlining von Funktionen, da es mglich gemacht werden muss, einen Verweis auf die nicht-inline-fhige Funktion bereitzustellen, wenn arguments.callee zugegriffen wird. arguments.callee fr Funktionen im Strict-Modus ist eine nicht lschbare Eigenschaft, die beim Setzen oder Abrufen einen Fehler wirft:
"use strict";
function f() {
return arguments.callee;
}
f(); // throws a TypeError
Reservierte Wrter sind Bezeichner, die nicht als Variablennamen verwendet werden knnen. Im Strict-Modus sind einige Namen reserviert, die im Sloppy-Modus nicht reserviert sind, von denen einige bereits in der Sprache verwendet werden, und einige sind fr die Zukunft reserviert, um zuknftige Syntaxerweiterungen leichter implementierbar zu machen.
Der Strict-Modus wurde so konzipiert, dass der bergang zu ihm schrittweise erfolgen kann. Es ist mglich, jedes einzelne Datei individuell zu ndern und sogar Code bis zur Funktion granular in den Strict-Modus zu berfhren.
Sie knnen eine Codebasis in den Strict-Modus migrieren, indem Sie zunchst "use strict" zu einem Stck Quellcode hinzufgen und dann alle Ausfhrungsfehler beheben, whrend Sie auf semantische Unterschiede achten.
Beim Hinzufgen von 'use strict'; werden die folgenden Flle einen SyntaxError werfen, bevor das Skript ausgefhrt wird:
const n = 023;with-Anweisungdelete bei einem Variablennamen delete myVariable;eval oder arguments als Variable oder Funktionsargumentnameimplements, interface, let, package, private, protected, public, static, und yieldfunction f(a, b, b) {}{a: 1, b: 3, a: 7}. Diese Einschrnkung wurde spter entfernt (Bug 1041128).Diese Fehler sind gut, weil sie klare Fehler oder schlechte Praktiken offenlegen. Sie treten auf, bevor der Code ausgefhrt wird, sodass sie leicht zu entdecken sind, solange der Code von der Laufzeitumgebung geparst wird.
JavaScript versagte frher stillschweigend in Kontexten, in denen das, was getan wurde, ein Fehler sein sollte. Der Strict-Modus wirft in solchen Fllen. Wenn Ihre Codebasis solche Flle enthlt, wird ein Test notwendig sein, um sicherzustellen, dass nichts kaputt geht. Sie knnen solche Fehler auf Funktionsebene ausfiltern.
ReferenceError. Dies stellte frher eine Eigenschaft auf dem globalen Objekt ein, was selten der erwartete Effekt ist. Wenn Sie wirklich einen Wert auf dem globalen Objekt setzen mchten, weisen Sie ihn explizit als Eigenschaft auf globalThis zu.TypeError. Im Sloppy-Modus wrde dies stillschweigend scheitern.TypeError. Im Sloppy-Modus wrde dies stillschweigend scheitern.arguments.callee, strictFunction.caller, oder strictFunction.arguments wirft einen TypeError, wenn die Funktion im Strict-Modus ist. Wenn Sie arguments.callee verwenden, um die Funktion rekursiv aufzurufen, knnen Sie stattdessen einen benannten Funktionsausdruck verwenden.Diese Unterschiede sind sehr subtile Unterschiede. Es ist mglich, dass eine Testreihe diese Art von geringfgigen Unterschieden nicht erfasst. Eine grndliche berprfung Ihrer Codebasis wird wahrscheinlich notwendig sein, um sicherzustellen, dass diese Unterschiede die Semantik Ihres Codes nicht beeinflussen. Glcklicherweise kann diese grndliche berprfung schrittweise auf Funktionsebene durchgefhrt werden.
thisIm Sloppy-Modus wrden Funktionsaufrufe wie f() das globale Objekt als this-Wert weitergeben. Im Strict-Modus ist es jetzt undefined. Wenn eine Funktion mit call oder apply aufgerufen wurde, wrde der Wert in ein Objekt geboxet werden (oder das globale Objekt fr undefined und null). Im Strict-Modus wird der Wert direkt ohne Konvertierung oder Ersatz bergeben.
argumentsIm Sloppy-Modus wrde das ndern eines Werts im arguments-Objekt das entsprechende benannte Argument ndern. Dies machte Optimierungen fr JavaScript-Engines kompliziert und den Code schwerer zu lesen/verstehen. Im Strict-Modus wird das arguments-Objekt erstellt und mit den gleichen Werten initialisiert wie die benannten Argumente, aber nderungen am arguments-Objekt oder den benannten Argumenten werden nicht gegenseitig widergespiegelt.
evalIm Strict-Modus-Code erstellt eval keine neue Variable im Scope, von dem aus es aufgerufen wurde. Natrlich wird im Strict-Modus die Zeichenfolge mit Strict-Modus-Regeln ausgewertet. Eine grndliche Testung wird erforderlich sein, um sicherzustellen, dass nichts kaputtgeht. Nicht-verwenden von eval, falls Sie es nicht wirklich bentigen, knnte eine andere pragmatische Lsung sein.
Im Sloppy-Modus kann eine Funktionsdeklaration in einem Block auerhalb des Blocks sichtbar und sogar aufrufbar sein. Im Strict-Modus ist eine Funktionsdeklaration in einem Block nur innerhalb des Blocks sichtbar.
| Spezifikation |
|---|
| ECMAScript 2027 LanguageSpecification |
Der Bauplan fr ein besseres Internet.
Teile dieses Inhalts sind 19982026 von einzelnen mozilla.org-Mitwirkenden. Inhalte sind verfgbar unter einer Creative-Commons-Lizenz.
| Web Proxy Viewer | New URL | Original Page |