Javascript globale und lokale Variable

Javascript Variablen, block scope

Javascript-Variablen, die nicht innerhalb von Funktionen oder ohne eines der Schlüsselwörter let, const oder var vereinbart werden, werden globale Variablen genannt. Sie sind im gesamten Code bekannt.

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

Block Scope in C-Sprachen

Globale Variablen sind Tretminen, denn weitere Scripte könnten sie unwissentlich mit demselben Namen überschreiben. Da Webseiten mehrere Scriptdateien laden können, passiert dieses Unglück schnell und diese Fehlerquelle versteckt sich ausgesprochen gut. Die Folge ist kein einfacher Syntaxfehler, sondern ein Logik- oder Rechenfehler, den erst eine akribische Feinarbeit entlarvt.

Programmiersprachen mit einer C-Syntax haben einen Block Scope – alle Variablen, die innerhalb von geschweiften Klammern {in einem Block} definiert werden, gelten nur innerhalb dieses Blocks und sind lokale Variablen.

Der Scope ist der Gültigkeitsbereich einer Variablen. Ein Block aus Anweisungen innerhalb von geschweiften Klammern ist ein { Block Scope }.

Block Scope in C-Sprachen
Erzeugt einen Fehler (xtra ist nicht definiert) in C-Sprachen
{
   var xtra;   // gilt nur innerhalb der geschweiften Klammern
   xtra = 15;
}
xtra = 500;

Erst ECMAScript 6 hat die geschweiften Klammern zum Block-Scope gehieft, allerdings nur für Variablen, die mit let / const deklariert wurden. Die Deklaration von Variablen mit dem Schlüsselwort var ist heute eine veraltete Technik, der wir aber noch in älteren Scripten begegnen.

Javascript Scope

Scope kann man mit dem Dateisystem – Ordnern und Dateien – des Computers vergleichen. Nehmen wir einen Ordner Scope1 und füllen ihn mit Dateien d1, d2, d3, …. Das Verzeichnis wird wie folgt aussehen:

Dateien im Ordner Scope01 Dateien im Ordner Scope02
In beiden Ordnern liegen Dateien mit dem Namen d3 ohne sich zu stören. Das könnten dieselben oder auch verschiedene Dateien sein – ihre Ordner schützen sie vor Verwechseln und Überschreiben.

Auf die Dateien unterhalb eines Ordners greift der Vorwärts-Slash (bzw. Rückwärts-Slash) zu:

scope01/d1
scope01/d2
scope01/d3

Ein Javascript-Objekt nutzt den Punkt anstelle des Slash.

const scope01 = {};
scope01.d1;
scope01.d2;
scope01.d3;

Dieses Prinzip gilt nicht nur für Javascript-Objekte, sondern greift bei Funktionen. IFFE (Immediately Invokable Function Expressions) und Javascript class (ES6) bilden Scopes genauso wie while- und for-Schleifen und if-Anweisungen. Alles in geschweiften Klammern ist ein Scope.

Ordnerstrukturen lassen sich verschachteln – dasselbe gilt für den Scope.

Lokale und globale Variablen

In JavaScript entstehen globale Variablen auf dreierlei Weise:

  1. wenn sie nicht durch var, let oder const deklariert wurden,
  2. bei einer Deklaration außerhalb aller Funktionen, Objekte, Klassen und geschweiften Klammern,
  3. bei einer Wertzuweisung innerhalb einer Funktion, ohne dass die Variable zuvor durch var, let oder const deklariert wurde.

Variablen, die mit let oder const angelegt werden, gelten nur innerhalb ihres Blocks und Code außerhalb des Block kann ebenfalls nicht auf diese Variablen zugreifen. 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.

Variablen in Funktionen, die durch das Schlüsselwort var deklariert wurden, galten nur innerhalb der Funktion. Code außerhalb der Funktion konnte auf diese Variablen nicht zugreifen – eine lokale Variable ist entstanden. Wird außerhalb der Funktion eine Variable mit demselben Namen deklariert, benutzt die Funktion immer die lokale Variable aus ihrem Funktionskörper. Man spricht bei dieser Mimic auch von einem Gültigkeitsbereich der Variablen – ihrem Scope.

Function Scope mit var

Javascript hatte ursprünglich keinen Block Scope, sondern bis ES2015 gab nur einen Function Scope. Javascript Variable, die innerhalb von Funktionen mit var definiert wurden, waren lokale Variablen. Alle anderen Variablen waren globale Variablen im gesamten Programm.

Function Scope in Javascript
function foo (){
   var xtra;
   xtra = 14;
}
myVal = xtra; 

erzeugt eine Fehlermeldung

Can't find variable: xtra

Aber auch innerhalb von Funktionen werden Variablen intern immer wie mit einem Aufzug nach oben an den Anfang der Funktion gehoben (hoisted): Sie gelten innerhalb der ganzen Funktion.

var xtra = "GLOBAL";

function foo () {
  xtra = "LOKAL";
  var xtra;
	
  console.log ("xtra lokal " + xtra);
}
foo ();
console.log ("xtra global " + xtra);
[Log] xtra lokal LOKAL
[Log] xtra global GLOBAL
var xtra = "GLOBAL";

function foo () {
  xtra = "LOKAL";
  //var xtra;
	
  console.log ("xtra lokal " + xtra);
}
foo ();
console.log ("xtra global " + xtra);
[Log] xtra lokal LOKAL
[Log] xtra global LOKAL

Scope – Gültigkeitsbereich für var (global / lokal)

Der Scope oder Gültigkeitsbereich einer Variablen beschreibt, wo eine Variable innerhalb eines Programms verfügbar ist und benutzt werden kann. Javascript-Variablen sind entweder global oder lokal. Auf eine globale Variable kann von jeder Stelle des Programms aus zugegriffen werden – sie gilt im gesamten Javascript-Programm und ist ein Hort für Fehlerquellen.

Programmbereich – Scope
Zeigt, welche Variable in welchem Programmbereich – Scope – aufgerufen werden kann.

Normalerweise soll eine Variable nur in einem bestimmten Bereich des Scripts gelten. Das vermeidet Namenskonflikte und das unabsichtliche Ändern von Variablen in anderen Teilen des Scripts. Wenn Scripte von Dritten (z.B. für Galerien und Effekte) eingesetzt werden, potenzieren sich die Fehlerquellen durch globale Variable und werden zu Tretminen.

Wenn eine Variable innerhalb einer Funktion mit dem Schlüsselwort var deklariert wird, ist diese Variable lokal. Auf lokale Variablen kann nur innerhalb der Funktion zugegriffen werden, in der die Variable vereinbart wird – und zwar von der Stelle der Vereinbarung an bis zum Ende des Blocks.

Diese Technik hat eine angenehme Nebenwirkung: Lokale Variable geben beim Verlassen der Funktion ihren Speicherplatz frei.

Javascript const und let – Blockscope oder Gültigkeitsbereich

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 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'.

Auf sicher gehen: ECMAScript 2015 oder IIFE

let und const werden von allen modernen Browsern unterstützt, Internet Explorer ab IE11. Wer ältere Browser mitziehen will, aber dennoch wie in C-Sprachen mit let und const sicherer programmieren möchte, kann z.B. den Babel-Javascript-Compiler einsetzen.

<div id="output"></div>
<!-- Load Babel -->

<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- Your custom script here -->
<script type="text/babel">
const getMessage = () => "Hello World";
document.getElementById('output').innerHTML = getMessage();
</script>

Wer auf der anderen Seite lieber die Abhängigkeit von Librarys einschränkt, nutzt IIFE – Self Executing Functions – selbst ausführende Funktionen –, um einen Block-Scope zu erzwingen.

for (var i = 0; i < 10; i++) {
  (function(c) {
    es[i] = function () {
      console.log("Upcoming edition of ECMAScript is ES" + c);
    };
  }(i));
}

Quelle How to have block scopes in ECMAScript 5

Jede Variable, die in den Block-Scope versetzt werden soll, wird zum Parameter der Funktion und initiale Werte werden als Argument übergeben. Das ist ein vertrautes Muster: So beginnen Libraries wie jQuery und viele andere kleine Helfer.

Gute Programmierpraxis

  • In den meisten Programmiersprachen sollen Variablen – soweit es möglich ist – lokal gehalten werden 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; <brselbst ausführende Funktionen> width = 200;
    ist besser als
    h = 115;
    w = 200;
  • Variablennamen wie name1 und name2 sind der schnellste Weg zu Nervenkrisen und Hysterie.