Grundlegende Bausteine, Strukturen und Verhaltensweisen von JavaScript
Literale
JS Programme sind auf elementarster Ebene Mengen von Konstanten, Variabl-, Operator-, Funktions und Objektnamen. Die zur Bennenung nutzbaren Namen müssen regulär sein:
- müssen mit einem Buchstaben, dem Unterstrich _ oder $ beginnen
- dürfen nur aus Buchstaben, Ziffern, _ und dem $ bestehen
- dürfen keine Leerraumzeichen enthalten
Global Scope
Alle Variablen, Funktionen oder Objekte sind entweder direkte Eigenschaften oder Methoden eines globalen Objektes, oder Bestandteile der Implementierung dieser direkten Eigenschaften und Methoden. Das globale Objekt im Browser ist das window Objekt.
Auf die Eigenschaften und Methoden kann stets zugegriffen werden. Dieser öffentliche Zugriff wird als global Scope bezeichnet.
Das globale Objekt kann jederzeit durch definieren globaler Variablen um Eigenschaften und Methoden erweitert werden. Globale Variablen können außerhalb als auch innerhalb von Funktionsblöcken definiert werden. Im Vergleich zu weit verbreiteten Programmiersprachen wie C++ ist das ungewöhnlich, und für den JS Anfänger eine permanente Fehlerquelle !
// globale Variable als Zustandsschalter für gesamte Applikation First = true; function ErzeugungsmusterFuerGlobaleVariablen() { // Demo der Erzeugung und Initialisierung globaler Variablen aus einer Funktion heraus. // Ohne vorangestelltes Schlüsselwort var werden auch innerhalb eines Funktionsblockes immer // !globale! Variablen definiert ! console.log("globale Counter werden erzeugt."); // Initialisierung in Abhänkgigkeit vom Zeitpunkt der Ausführung über // zentrale globale Variable First steuern. if (First) { // Legt !globale! Variable Count an ! Count = 1; First = false; } else { Count++; } // Alternative 1: Prüfen, ob Variable bereits definiert wurde mittels typeof === "undefined" Idiom if (typeof Count1 === "undefined") { // Variable existiert noch nicht Count1 = 1; } else { Count1++; } // Alternative 2, ohne Schalter First: Ausnutzung von lazy evaluation logischer Ausdrücke // Auch hier wird eine globale Variable, falls noch nicht existent, erzeugt und initialisiert. Count2 = (window.Count2 || 1) + 1; var Count3 = window.Count3; }
strict mode
Ab ES5 kann die Erzeugung globaler Variablen durch den
strict mode
abgeschaltet werden. Der strict mode wird durch das String- Literal "use strict";
für
das gesamte Programm, oder nur für eine Funktion eingeschaltet:
// aktiviert den Strict- Mode für das gesamte Script "use strict"; function f() { // Aktiviert den Strict- Mode nur innerhalb von f "use strict"; }
Der Strict- Mode unterdrückt eine Reihe von altbekannte JavaScript Problemen wie :
- Mehrfachdefinition eines Parameter:
function f(a, a, b)
- Den with- Block:
var x = 0; with(obj) { x= 1; // ? x==1 oder obj.x == 1 }
- Deklaration globaler Variablen in Funktionen:
function f() {X = 1;} console.assert(X == 1);
Lokale Variablen mittels var
Mittels des Schlüsselwortes var
können globale als auch lokale Variabledeklarationen
ausgezeichnet werden:
// globale Variable, ausgezeichnet mit dem Schlüsselwort var (optional) var x = "global"; function f() { // lokale Variabledeklaration, die das globale x überdecken soll // -> var ist obligatorisch var x = "local"; console.assert(window.x === "global"); console.assert(x === "local"); }
Hoisting
Bis ES6 gab es in JavaScript keinen BlockScope ! Nur Funktionsblöcke definieren eigene Sichtbarkeitsbereiche (Scopes). Dies führt dazu, das scheinbar lokale Variablen innerhalb von Kontrollstrukturblöcken wie IF in der gesamten Funktion sichtbar sind. Dies kann zu ungewollten Fehlern führen !
IFFE- Blöcke
Abhilfe gegen das Hoisting sind IFFE Blöcke. IFFE steht für Immediatly Invoked Function Expressions. Die lokalen Variablen werden in Funktionsblöcke eingeschlossen, die sofort ausgeführt sind. Das Muster ist wie folgt:
// IFFE- Block (function(){ var x ... })(); // +-> Funktion wird sofort aufgerufen.
Blockscope ab ES6
Ab ECEMA Script 6 (kurz ES6) gibt es in JS einen echten Blockscope: die Sichtbarkeit und Lebensdauer kann durch die Blockgrenzen
beschränkt werden. Dazu ist die Variable mittels des Schlüsselwortes let
zu deklarieren anstelle var
: