Javascript globale und lokale Variable

Variable, die nicht innerhalb von Funktionen oder ohne eines der Schlüsselwörter let, const oder var vereinbart sind, werden globale Variable genannt. Sie sind im gesamten Skript bekannt, können jederzeit überschrieben werden, Namenskonflikte erzeugen und erschweren die Suche nach Fehlern.

Javascript Variablen, block scope

Globale Variablen sind Tretminen

Da Webseiten mehrere Scriptdateien laden können und viele globale Variable zusammenkommen, passiert ein Missgeschick schnell. Fehlerquellen durch globale Variablen verstecken sich ausgesprochen gut.

let data = [];
let user = [];
let config = [];

function foo() {
	const user = ["admin", "author", "user"];
	console.log ("user", user);
}

console.log ("user", user);
foo();

Ein Klassiker unter den Fehlern, die durch globale Variable entstehen: Obwohl user nur unter bestimmten Bedingungen existieren sollte (… if (true) …) wird der Benutzer durch den Aufruf von createUser auf jeden Falle erzeugt.

function createUser() {
	if (true) {
		user = { name: "Horst", age: 12 };   // keine Deklaration!
	}
}

createUser();

console.log(user);

Die Folge ist kein einfacher Syntaxfehler, sondern ein Logik- oder Rechenfehler, den erst eine akribische Feinarbeit entlarvt.

Wie entstehen globale Variablen?

In JavaScript entstehen globale Variablen auf dreierlei Weise:

  1. wenn sie nicht durch var, let oder const deklariert wurden,
    function foo () {
    	user = [
    		{name: "Horst", age: 12}, 
    		{name: "Martin", age: 8}
    	];
    }
    
  2. bei einer Deklaration außerhalb aller Funktionen, Objekte, Klassen und geschweiften Klammern
    let user = "Jack Global"; // global verfügbar
  3. bei einer Wertzuweisung innerhalb einer Funktion, ohne dass die Variable zuvor durch var, let oder const deklariert wurde
    function foo() {
    	unabsichtlichGlobal = 42;  // Ohne 'var', 'let' oder 'const' → globale Variable
    }
    foo();
    console.log(unabsichtlichGlobal);  // 42

Schutz vor globalen Variablen

"use strict";

"use strict"; ist eine der ältesten Maßnamen zum Schutz vor globalen Variablen.

"use strict";
user = "Helmut";

function foo () {
	user = [
		{name: "Horst", age: 12},
		{name: "Martin", age: 8}
	];
}

foo();
console.log ("user", user)
ReferenceError: Can't find variable: user
Variablen immer deklarieren

Gute Programmierpraxis ist natürlich: Variablen immer mit let oder const deklarieren!

Variablen, die mit let oder const angelegt werden, gelten nur innerhalb ihres Blocks und Code außerhalb des Block kann nicht auf diese Variablen zugreifen.

{} - Blöcke

let und const innerhalb Blöcken sind immer lokale Variablen. Das klingt zwar für Einsteiger erst einmal unbequem, aber verhindert viele schwer aufzudeckende Fehler.

function foo () {
	const user = [
		{name: "Horst", age: 12},
		{name: "Martin", age: 8}
	];
}
IIFE

IIFE – Weil Variablen innerhalb der geschweiften Klammern von Funktionen geschützt waren, wurden Immediately Invoked Funktion Expression (IIFE) eingesetzt. Wird außerhalb der Funktion eine Variable mit demselben Namen deklariert, benutzt die Funktion immer die lokale Variable aus ihrem Funktionskörper. Mit IIFE entsteht ein »Funktions-Scope«, der sofort ausgeführt wird. Gegen vergessene Deklarationen helfen IIFE allerdings auch nicht.

(function () {

	function createUser() {
		if (true) {
			let user = { name: "Horst", age: 12 };
		}
	}

	createUser();

})();

console.log(user); // ReferenceError

Man spricht bei dieser Mimic auch von einem Gültigkeitsbereich der Variablen – ihrem Scope.

Namespace

Wenn Variablen global sein müssen, hilft ein Namespace-Objekt.

const App = {};

App.user = { name: "Horst" };

App.createUser = function() {
	return { name: "Martin" };
};

Block-Scope und Function-Scope – Gültigkeitsbereich von Variablen

Globale Variablen gelten im gesamten Programm. Javascript hatte ursprünglich keinen Block Scope, sondern bis ES2015 gab es nur einen Function Scope.

Mit ES6 (ECMAScript 2015) hat Javascript let und const für die Deklaration von Variablen bzw. Konstanten hinzu bekommen, die wie C-Sprachen mit dem eingeschränkten Gültigkeitsbereich ihres umfassenden Blocks (nur innerhalb von { und }) arbeiten. Das reduziert die möglichen Fehlerquellen.

(Die konfusen Namen ES6, ECMAScript 2015: Version 6 von ECMAScript wurde umbenannt in ECMAScript 2015 oder ES2015)

const name = "ECMA";
if (name === "ECMA") {
   let hallo = "Hallo Javascript";
} else {
   let hallo = "Hallo";
}

console.log (hallo);

Führt zu einer Fehlermeldung, denn hallo ist nur innerhalb der geschweiften Klammern des if-Blocks bekannt.

ReferenceError: Can't find variable: hallo

let bringt noch eine weitere Sicherheitsvorkehrung mit. Wird ein Variablennamen innerhalb eines Blocks mehrfach verwendet, wirft Javascript einen Fehler aus.

if (x > 0 ) {
   let togo = "cofe to go";
   let togo = "Kinderkram";
}
SyntaxError: Cannot declare a let variable twice: 'togo'.

Gute Programmierpraxis

  • Variablen sollen – soweit es möglich ist – lokal gehalten und dort vereinbart werden, wo sie auch gebraucht werden. Das hilft bei der Fehlersuche und macht das Skript lesbarer. In Javascript macht es Sinn, die Variablen zu Beginn der Funktion zu definieren. Das vermeidet, dass Variablennamen innerhalb der Funktion mehrfach vergeben werden.
  • Variablen sind case-sensitiv, also immer darauf achten, dass aName eine andere Variable als AName ist.
  • Variablennamen sollten sich aussprechen lassen und eine sinnvolle Bezeichnung ergeben.
    height = 115;
    width = 200;

    ist besser als
    h = 115;
    w = 200;
  • Variablennamen wie name1 und name2 sind der schnellste Weg zu Nervenkrisen und Hysterie.
Suchen auf mediaevent.de