Strict Mode – sei streng
Auch mit dem modernen JavaScript (ECMAScript 6 und jünger) ist use strict ein sinnvolles Werkzeug zur Vermeidung stiller Fehler und unsicherer Konstrukte. Der nachsichtige Umgang von JavaScript mit kleinen Fehlern war und ist immer noch ein Handicap. use strict meldet sich bei fehlenden Semikolons, verbietet with, unterwandert eval und reserviert neue Namen für spätere Versionen (package, private, protected, pbulic, static, yield).
In Webseiten benutzen wir Javascript oft noch nach den lausigen Regeln von ECMAScript 3, aber die Angabe von
"use strict";
am Anfang des Scripts oder (besser) am Anfang von Funktionen fordert saubere Programmierung. Der strict mode ist nicht einfach eine Untermenge des normalen Sprachumfangs. JavaScript-Engines wie V8 in Chrome können den Code im Strict Mode effizienter optimieren, da sie bestimmte Optimierungen nur auf strikt-konformem Code anwenden. Der Strict Mode beseitigt unsichere Praktiken, was der Engine hilft, JavaScript schneller zu analysieren und auszuführen.
Variablen immer deklarieren
Wenn use strict gesetzt ist, müssen Variablen deklariert werden. Das vermeidet überflüssige und gefährliche globale Variablen. Wenn Variablen nicht deklariert sind, steigt das Script mit einer Fehlermeldung aus.
"use strict"; hal = "Hallo World!";
Die Fehlermeldung hat zwar in allen Browsern einen anderen Dialekt, aber die Fehlerursache ist schnell ausgemacht:
ReferenceError: Can't find variable: hal oder ReferenceError: assignment to undeclared variable hal oder Variable undefined in strict Mode oder Uncaught ReferenceError: hal is not defined
Ohne strict würde die undeklarierte Variable hal zu einer globalen Variablen und kann zu schwer auffindbaren Logikfehlern führen. Das passiert selbst sorgfältigen Programmierern: Man definiert eine Variable brav mit let foo, aber durch einen Tippfehler entsteht die Variable fuu und wird zu einer neuen globalen Variablen.
Mit use strict werden doppelte Parameternamen in Funktionen und Objekten erkannt
"use strict"; const myObject = { aName: 1, aName: 2 } function myFunction(a,b,a) { return a + b + c; }
Auch wenn die ganz alte Generation der Browser use strict nicht erkannte – der Test mit einem aktuellen Browser bringt Abwege und Fallen ans Tageslicht. Allerdings schützt use strict nicht vor fehlerträchtigen oder sogar böswilligen Scripten aus externen Quellen.
Brauchen wir heute noch use strict?
Wenn wir heute Javascript-Klassen und -Module benutzen, brauchen wir den strict-Mode tatsächlich nicht mehr, denn sie schalten die strict-Direktive automatisch ein.
Was geht nicht im Strict Mode?
- Keine impliziten globalen Variablen in Funktionen
- apply und call fallen nicht per default an das globale Objekt
- with gibt es nicht mehr
- arguments.caller oder arguments.callee sind versenkt
- Doppelte Namen erzeugen einen Syntax-Fehler
- Hinweg mit oktalen Literals (let num = 013 führt zu einem Syntaxfehler: Decimal integer literals with a leading zero are forbidden in strict mode)
Böses eval
eval ist schon lange eine unerwünschte Funktion. Unter strict ist nahezu alles mit eval streng untersagt und wird sofort geblockt.
obj.eval = ... obj.foo = eval; let eval = ...; ++eval; for ( let eval in ... ) {} function eval() {} function test(eval) {} function(eval){} new Function("eval") eval("let a = false;");
Wenn mehrere Scripte für eine Seite benutzt werden, ist es in Hinsicht auf die Performance besser, die Scripte nach den Tests in einer Script-Datei zusammenzufassen. Dann muss nur sichergestellt werden, dass die Zeile use strict nur am Anfang dieser einen Javascript-Datei steht.
Funktionen mit strict
strict muss nicht unbedingt gleich für das gesamte Script gelten, sondern kann in Javascript-Funktionen gesetzt werden. Bereiche außerhalb der Funktionen sind dann vom strict nicht betroffen.
Da heute Content Management Systeme alle Scripte aus einzelnen Modulen oder Plugins nach Möglichkeit zu einer großen Script-Datei zusammenwerfen, sind Funktionen der bessere Platz für use strict. Ansonsten könnte das erste Script mit einem globalen use strict alle folgenden Scripte in den Abgrund ziehen.
Der strict-Mode meldet sich nicht nur bei Syntaxfehlern, sondern weist auf potentielle Schwachstellen und Gefahrenquellen hin. Besonders wenn Scripte von Dritten eingesetzt werden, macht ein Testen der Scripte im strict-Mode Sinn, um einen Eindruck von der Qualität des Scripts zu gewinnen.
strict für externe Scripte
Wäre es nicht praktisch, use strict für externe Scripte einzusetzen, z.B. um die Gefahr von Injections durch evel() zu erkennen? Geht aber nicht.
<script>
"use strict";
console.log("A: Dieses Script ist im Strict Mode");
function f() {
return g(3);
}
</script>
<script src="external.js"></script> //vereinbart Funktion g()
<script>
f();
console.log("B: Dieses Script-Element ist nicht strikt.");
</script>
Quelle Stackoverflow: Do we need to put “use strict” in external js files if our html file already has “use strict”?
Script im strict mode?
Es gibt keinen Hinweis, keine Methode, kein Objekt in Javascript, dass anzeigt, ob das Script im Strict Mode ausgeführt wird oder nicht.
Selber programmieren:
"use strict"; function isStrict () { return ( function () { return !this; }()); } console.log ("isStrict " + isStrict());
Die häufigsten Syntaxfehler
- Fehlen schließende runde oder geschweifte Klammern?
- Fehlt ein schließendes Hochkamma oder wird ein doppeltes Hochkomma durch ein einfaches Hochkomma geschlossen?
- Klammer zuviel im Script-Code?
- Bindestrich im Variablennamen? Javascript mag keine Bindestriche.
- Groß und Kleinschreibung beachtet? Hier ist Javascript tatsächlich empfindlich
- Schreibfehler in einer der DOM-Methoden? Vor allem getElementById macht schnell Ärger.