Javascript use strict

Strict Mode erzwingt saubere Programmierpraxis

Mit use strict aus ECMAScript 5 zieht Disziplin ins Programmierstübchen. strict mode ist keine Anweisung, sondern bringt eine leicht abweichende Semantik und fordert die Einhaltung strikter Programmierkonventionen, um typische Fehlerquellen im Vorfeld zu vermeiden (z.B. die Verwendung undefinierte Variablen, fehlende Semikolons).

Für die neue Generation von Javascript-Anwendungen ist der liebevolle Umgang mit den kleinen Fehlern ein Handicap.

Strict Mode – sei streng

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 – für Browser, die strict mode nicht unterstützen (IE8, IE9), waren sorgfältige Tests angesagt.

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";

let myObject = {
	aName: 1,
	aName: 2
}

function myFunction(a,b,a) {
	return a + b + c;
}

Nicht alle Browser erkennen use strict. Da use strict aber eine einfache String-Anweisung ist, überlesen diese Browser die Option. Firefox 4, Chrome 13, Opera 11.6 und Safari 5 erkennen den strict-Modus von Javascript, Internet Explorer ab Version 10. Sie brechen dann die Ausführung bei den typischen Nachlässigkeitsfehlern ab.

Auch wenn alte Browser use strict nicht erkennen – 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.

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 ist 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.
use strict