JavaScript/strict mode
In JavaScript gibt es aufgrund der bewegten Geschichte mit vielen proprietären Methoden und der sehr einfachen Möglichkeit, globale Variablen einzuführen, viele potentielle Fehlerquellen. Deshalb wurde mit ECMA5 der Strenge Modus (strict mode) eingeführt, der ein standardisiertes, um Fehlerquellen bereinigtes, Subset der Programmiersprache aktiviert. Die Arbeitsweise von JavaScript außerhalb des strengen Modus bezeichnet man salopp auch als sloppy mode (schlampig, schluderig).
Inhaltsverzeichnis
Aktivierung des strict mode
Der strenge Modus lässt sich für ein komplettes Script-Element oder nur für einzelne Funktionen aktivieren. Dazu ist zu Beginn das merkwürdig aussehende Statement 'use strict';
zu notieren.
'use strict';
x = 42;
Normalerweise würde aus dieser Zuweisung eine globale Variable entstehen, die dann in anderen Teilen des Programms zu unerwünschten Konsequenzen führen kann.
Durch die Angabe von 'use strict';
wissen die Browser, dass sie einen strengeren Maßstab anlegen müssen und lösen eine Fehlerbedingung (ReferenceError) aus, da die Variable nicht deklariert ist. Ältere Browser sehen in 'use strict';
nur einen reinen String, den sie ignorieren (formal ist es so, dass ein Ausdruck ein gültiges Statement darstellt. Eine Konstante ist die einfachste Form eines Ausdrucks).
'use strict';
!
Deklarieren Sie globale Variablen am Anfang des Scripts mit var
oder const
(wenn sie sich nicht mehr verändert)!Wenn Sie nicht komplette Programme in den Strengen Modus versetzen wollen, können Sie ihn nur auf einzelne Funktionen beschränken:
// Hier besteht kein strict mode, die Zuweisung erzeugt eine globale Variable
x = 42;
// Zuweisung an undeklarierte Variable innerhalb einer Funktion im Strict Mode
function zuweisungStrict(){
'use strict';
name = "Arthur Dent";
}
zuweisungStrict(); // Löst einen ReferenceError aus
Achtung!
- In ECMAScript-Modulen (eingebunden mit
<script type="module">
) - In Klassen, die mit dem
class
-Schlüsselwort deklariert wurden
Auswirkungen des strict mode
Variablen müssen deklariert werden
Zuweisungen ohne var
werden in JavaScript (wie im oberen Codebeispiel) zu globalen Variablen. Auch ein reiner Tippfehler führt zu einer neuen globalen Variable:
var variableX = 42; // Zuweisung als globale Variable
function zuweisungZahl() {
variabelX = prompt("Geben Sie eine neue Zahl ein", "");
}
Durch die falsche Schreibweise von variableX
wird der Wert nicht überschrieben, sondern eine neue globale Variable angelegt.
Im 'strict mode'
würde es einen 'ReferenceError'
geben.
Globale Variablen können später unerwünschte Konsequenzen auslösen.
- Gleich benannte globale Variablen unterschiedlicher Scripte überschreiben sich gegenseitig
- Ein Tippfehler beim Programmieren kann unbemerkt eine neue Variable erzeugen, während die eigentlich gemeinte Variable leer bleibt
Da solche keine Syntaxfehler sind, kann man sie nur sehr schwer debuggen.
Fehler werden sichtbar
JavaScript war als anfängerfreundliche Sprache konzipiert, die bei Fehlern nicht sofort abbrechen sollte. So werden bei einigen Programmierfehlern (mistakes) die Fehlermeldungen unterdrückt. Während dies manchmal einen Abbruch des Programms verhindert, entstehen teilweise schwerwiegendere Fehler (error), die erst später sichtbar werden, wenn das Programm unerwartet abbricht. Zu diesem Zeitpunkt ist dann oft nicht mehr ersichtlich, welcher mistake ursprünglich verantwortlich war.
Im strict mode werden Meldungen für diese Fehler in der Konsole ausgegeben. So können Sie diese Fehler während des Entwickelns und Debuggens identifizieren, analysieren und beseitigen.
arguments
Beim Aufruf einer Funktion wird ein spezielles Objekt arguments
erzeugt, das die Argumente der Funktion wie in einem array
speichert.
function foo() {
bar(1, 2);
}
function bar(arg1, arg2) {
var temp = arguments[0];
arguments[0] = arg2;
arguments[1] = temp;
alert(arg1 + " " + arg2);
}
In diesem Beispiel haben arguments[0]
und arg1
sowie arguments[1]
und arg2
die gleichen Werte. Normalerweise wird bei der Änderung eines Werts der andere ebenfalls verändert. In der Funktion bar
werden die Werte von arg1
und arg2
getauscht, obwohl nur die Werte des arguments-Array verändert wurden.
Im strikten Modus ist dies nicht erlaubt; die Werte von arg1
und arg2
bleiben unverändert.
Das arguments
-Objekt enthält auch einen Zeiger auf die gerade ausgeführte Funktion. Mit arguments.callee
können Sie die Funktion referenzieren. Dies ist innerhalb von anonymen Funktionen sinnvoll, bei anderen Funktionen können Sie die Funktion mit ihrem Namen aufrufen.
Im strikten Modus ist der Aufruf von arguments.caller
und arguments.callee
nicht erlaubt.
Funktionsaufrufe
In JavaScript können Sie auch innerhalb von Block-Anweisungen Funktionsdeklarationen notieren. Sie werden unabhängig davon, wo sie im Quelltext stehen, gleich zu Beginn geparst und interpretiert. Das kann in manchen Fällen zu unerwartetem Verhalten führen.
if (true) {
function foo () {
return 'first';
}
} else {
function foo () {
return 'second';
}
}
foo(); // Manche Javascript-Engines führen die erste Funktion aus, manche die zweite.
Im strikten Modus gelten die Funktionsdeklarationen nur innerhalb ihres Anweisungsblocks. Der Aufruf von foo() außerhalb dieser Blocks bricht der Meldung ab, dass foo
nicht definiert sei.
Um dennoch Funktionen erstellen zu können, deren Implementierung von einer Bedingungen abhängig ist, können Sie eine Variable anlegen und ihr nach Bedarf eine anonyme Funktion zuweisen:
'use strict';
var foo;
if (true) {
foo = function () {
return 'first';
};
} else {
foo = function () {
return 'second';
};
}
foo(); // Jede Javascript-Engine führt die erste Funktion aus.
this
Wird eine Funktion normal aufgerufen (d.h. nicht als Methode), enthält this außerhalb des strict mode das globale Objekt. Dieses Verhalten wurde früher oft genutzt, um sich in Programmen, die nicht nur im Browser ausgeführt werden sollen, eine Referenz auf das globale Objekt zu verschaffen.
Im strict mode enthält this in solchen Funktionsaufrufen den Wert undefined
. Verwenden Sie die neue globale Variable globalThis
, die im Browser, in Workern und auch in node.js definiert ist, um auf das globale Objekt zuzugreifen. Vermeiden Sie außerdem, Variablen mit den Namen window
, self
, global
oder globalThis
zu definieren, weil diese Namen in verschiedenen Ausführungskontexten den Zugriff auf das globale Objekt bereitstellen. Wenn Sie sie für eigene Zwecke verwenden, können Sie den Zugriff auf das globale Objekt versperren.
with
Mit dem with-Statement konnten Sie mehrere Anweisungen in Folge notieren, die alle mit dem gleichen Objekt arbeiten.
with (document) {
open();
write("<p>Diese Seite hat den Titel " + title + "<\/p>");
close();
}
Da normalerweise mehrere Anweisungen folgen, die dieses Objekt verwenden, müssen Sie alle diese Anweisungen in geschweifte Klammern einschließen.
Achtung!
Im strict mode ist das with-Statement verboten und erzeugt einen Syntaxfehler![1]
Empfehlungen für die Praxis
'use strict';
!
'use strict';
führt dazu, dass Programmierer ...
- Fehler beim Entwickeln früher erkennen
- Scripts leichter debuggen können
- sich mehr Gedanken um den Geltungsbereich von Variablen machen
- letztendlich eine bessere Strukturierung und Kapselung der Scripts erreichen
Dieser Zwang zu mehr Disziplin ist insbesondere dann wichtig, wenn Code aus der Hand gegeben oder in Teamarbeit entwickelt wird.
Peter Kroener empfiehlt,'use strict';
beim Entwickeln zu verwenden und dann zu entfernen, um ältere Browser (und künftige Bugs) zu berücksichtigen. Allerdings setzt dies voraus, in der Programmierung auf Methoden, die im strengen Modus anders arbeiten, zu verzichten.[2]Weblinks
- ↑ yuiblog.com: With statement considered harmful
- ↑ Peter Kröner: Der Strict mode
- mediaevent: Strict mode
- MDN: Strict mode