Javascript globale und lokale Variable

Globale Variablen vs lokale Variablen, block scope und Schlüsselwort let Globus und ein paar verschmierte Striche

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.

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
Erzeugt einen Fehler (xtra ist nicht definiert) in C-Sprachen
{
   var xtra;   // gilt nur innerhalb der geschweiften Klammern
   xtra = 15;
}
xtra = 500;

Function Scope mit var

Javascript hingegen 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 Kran nach oben an den Anfang der Funktion gezogen: Sie gelten innerhalb der ganzen Funktion.

Block Scope mit let

Mit ES6 (ECMAScript 2015) sind let und const für die Deklaration von Variablen hinzugekommen, 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)

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

Scope – Gültigkeitsbereich 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.

Wo darf welche Variable aufgerufen werden? Zeigt, welche Variable in welchem Programmbereich – Scope – aufgerufen werden kann.
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. W enn Scripte von Dritten (z.B. für Galerien und Effekte) eingesetzt werden, potenzieren sich die Fehlerquellen durch globale Variablen 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. Innerhalb des Blocks überschreibt die Variable alle globalen Variablen mit demselben Namen, aber sie überschreibt keine globale Variable mit demselben Namen oder eine Variable in einer anderen Funktion.

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

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;
    width = 200;

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

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,
  3. bei einer Wertzuweisung innerhalb einer Funktion, ohne dass die Variable zuvor durch var, let oder const deklariert wurde.

Variablen in Funktionen, die durch das Schlüsselwort var deklariert sind, gelten nur innerhalb der Funktion. Code außerhalb der Funktion kann 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«.

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 lokalen Variablen. Das klingt zwar für Einsteiger erst einmal unbequem, aber verhindert viele schwer aufzudeckende Fehler.

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.

localVariable globalVariable var global = 100; var v = 200; var x = 500; function functionA () function functionB () var c = global + x; var y = global + x; var z = global + v; var w = global + x + y; gloable Variable lokale Variable