Читать книгу JavaScript – Das Handbuch für die Praxis - David Flanagan - Страница 148
5.6.3"use strict"
Оглавление"use strict" ist eine Direktive, die in ES5 eingeführt wurde. Direktiven sind keine Anweisungen (sind ihnen aber ähnlich genug, um "use strict" hier ebenfalls zu behandeln). Es gibt zwei wichtige Unterschiede zwischen der "use strict"-Direktive und regulären Anweisungen:
Sie enthält keine Schlüsselwörter: Die Direktive ist lediglich eine Ausdrucksanweisung, die aus einem speziellen String-Literal (in einfachen oder doppelten Anführungszeichen) besteht.
"use strict" darf nur am Anfang eines Skripts oder eines Funktionskörpers stehen, muss also jeder echten Anweisung vorausgehen.
Die "use strict"-Direktive zeigt an, dass der nachfolgende Code (eines Skripts oder einer Funktion) strikter Code ist. Code auf der obersten Ebene eines Skripts, der also nicht in einer Funktion steht, ist strikter Code, wenn das Skript eine "use strict"-Direktive enthält. Ein Funktionskörper ist strikter Code, wenn er in striktem Code definiert wird oder wenn er selbst eine "use strict"-Direktive enthält. Code, der einer eval()-Methode übergeben wird, ist dann strikter Code, wenn eval() aus striktem Code aufgerufen wird oder wenn er selbst eine "use strict"-Direktive enthält. Neben Code, der ausdrücklich als strikt deklariert wird, ist jeglicher Code in einem Klassenkörper (siehe Kapitel 9) oder in einem ES6-Modul (siehe 10.3) automatisch strikter Code. Liegt Ihr gesamter JavaScript-Code in Modulform vor, ist automatisch alles strikter Code, und Sie werden niemals eine explizite "use strict"-Direktive verwenden müssen.
Strikter Code wird im strikten Modus ausgeführt. Der strict-Modus ist eine beschränkte Untermenge von JavaScript, behebt einige relevante Mängel der Sprache und bietet eine strengere Fehlerprüfung sowie erhöhte Sicherheit. Da der strict-Modus nicht der Standardmodus ist, wird alter JavaScript-Code, der noch die mangelhaften Legacy-Funktionen der Sprache verwendet, weiterhin korrekt ausgeführt. Zwischen dem strict-Modus und dem normalen Modus gibt es folgende Unterschiede (die ersten drei sind besonders wichtig):
Die with-Anweisung ist im strikten Modus nicht erlaubt.
Im strict-Modus müssen alle Variablen deklariert werden: Wenn Sie einem Identifier einen Wert zuweisen, der keinen deklarierten Variablen, Funktionen, Funktionsparametern, Parametern einer catch-Klausel oder Eigenschaften des globalen Objekts entspricht, löst das einen ReferenceError aus. (Im nicht-strikten Modus wird dadurch hingegen implizit eine globale Variable deklariert, indem dem globalen Objekt eine neue Eigenschaft hinzugefügt wird.)
Bei Funktionen, die als Funktionen (und nicht als Methoden) aufgerufen wurden, hat this im strict-Modus den Wert undefined. (Im nicht-strikten Modus wird Funktionen, die als Funktionen aufgerufen werden, immer das globale Objekt als this-Wert übergeben.) Wird zudem im strict-Modus eine Funktion mit call() oder apply() (siehe 8.7.4) aufgerufen, wird als this-Wert das erste Argument von call() oder apply() verwendet. (Im nicht-strikten Modus werden null und undefined durch das globale Objekt ersetzt und Werte, die keine Objekte sind, in Objekte umgewandelt.)
Im strict-Modus wird bei Zuweisungen an nicht schreibbare Eigenschaften und bei Versuchen, neue Eigenschaften auf nicht erweiterbaren Objekten zu erstellen, ein TypeError ausgelöst. (Im nicht-strikten Modus scheitert beides ohne Fehlermeldung.)
Im strict-Modus kann Code, der an eval() übergeben wird, keine Variablen oder Funktionen im Geltungsbereich (Scope) des Aufrufers deklarieren bzw. definieren. Stattdessen existieren Variablen- und Funktionsdefinitionen in einem neuen Geltungsbereich, der speziell für eval() erstellt wird. Dieser Geltungsbereich wird verworfen, wenn eval() zum Aufrufer zurückkehrt.
Im strict-Modus enthält das Arguments-Objekt (siehe 8.3.3) einer Funktion eine statische Kopie der Werte, die der Funktion übergeben werden. Im nichtstrikten Modus verhält sich das Arguments-Objekt eher »magisch«: Die Array-Elemente und benannte Funktionsparameter verweisen beide auf den gleichen Wert.
Im strict-Modus wird ein SyntaxError ausgelöst, wenn auf den delete-Operator ein nicht qualifizierter Identifier wie eine Variable, eine Funktion oder ein Funktionsparameter folgt. (Im nicht-strikten Modus bleibt ein solcher delete-Ausdruck einfach wirkungslos und wird zu false ausgewertet.)
Im strict-Modus löst der Versuch, eine nicht konfigurierbare Eigenschaft zu löschen, einen TypeError aus. (Im nicht-strikten Modus schlägt der Versuch fehl, und der delete-Ausdruck wird zu false ausgewertet.)
Im strict-Modus ist es ein Syntaxfehler, wenn ein Objektliteral mehrere Eigenschaften mit dem gleichen Namen definiert. (Im nicht-strikten Modus tritt kein Fehler auf.)
Im strict-Modus ist es ein Syntaxfehler, wenn eine Funktionsdeklaration mehrere Parameter mit dem gleichen Namen hat. (Im nicht-strikten Modus tritt kein Fehler auf.)
Im strict-Modus sind keine oktalen Ganzzahlliterale erlaubt (also Literale, die mit einer 0 beginnen, auf die kein b, o oder x folgt). (Im nicht-strikten Modus erlauben einige Implementierungen Oktalliterale.)
Im strict-Modus werden die Identifier eval und arguments wie Schlüsselwörter behandelt. Ihr Wert darf nicht verändert werden. Sie können diesen Identifiern weder einen Wert zuweisen oder sie als Variable deklarieren noch sie als Namen für Funktionen, Funktionsparameter oder den Parameter eines catch-Blocks verwenden.
Im strict-Modus gibt es nur eingeschränkte Möglichkeiten, den Aufrufstapel zu untersuchen. arguments.caller und arguments.callee lösen in einer Funktion im strict-Modus beide einen TypeError aus. Funktionen im strict-Modus besitzen außerdem caller- und arguments-Eigenschaften, bei denen Leseversuche zu einem TypeError führen. (Einige Implementierungen definieren diese nicht dem Standard entsprechenden Eigenschaften auf nicht-strikten Funktionen.)