JavaScript/Variable

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Eine Variable lässt sich am besten mit einem Behälter, der genau einen Wert aufnehmen kann, vergleichen. Der Behälter ist ein logischer Speicherplatz mit einem (unveränderlichen) Namen und einem Wert, der verändert werden kann.

In JavaScript gibt es drei verschiedene Möglichkeiten Variablen zu deklarieren:

  • var: deklariert eine Variable unabhängig von ihrem Scope (Gültigkeitsbereich).
  • let: deklariert eine lokale Variable im Block Scope
  • const: Symbolische Konstante; deklariert eine unveränderliche Variable


var[Bearbeiten]

Der Titel dieses Artikels ist mehrdeutig.



Durch das Schlüsselwort var wird eine Variable vereinbart. Sie wird damit im aktuellen Scope (zum Beispiel innerhalb einer Funktion) angelegt. Ohne das Schlüsselwort var wird die Variable im globalen Scope erstellt.

  • JavaScript 1.0
  • Chrome
  • Firefox
  • IE
  • Opera
  • Safari

Sie kann entweder ohne Wert instantiiert werden:

Beispiel
var alter;

Oder der Anfangswert kann gleich angegeben werden:

Beispiel
var alter = 18;

Anstelle der 18 kann ein beliebiger Ausdruck stehen. Das Schema lautet also:

Beispiel
var Bezeichner = Ausdruck;

Wird ihr anfänglich kein Wert zugewiesen, so ist sie vom Typ undefined. Nachdem eine Variable erstellt wurde, kann mit dem Variablennamen gearbeitet werden. Das Speichern von Werten erfolgt über den Zuweisungsoperator.

Beachten Sie:
  • Bei der Vergabe von Variablennamen gelten die Regeln für selbstvergebene Namen.
  • Beim Arbeiten mit Variablen sucht der Interpreter die Variable zuerst im lokalen und anschließend im übergeordneten bis hin zum globalen Sichtbarkeitsbereich. Handelt es sich um eine Wertabfrage und findet er die Variable nicht, so löst er eine Ausnahme aus. Handelt es sich hingegen um eine Wertzuweisung und existiert die Variable nicht, dann erstellt der Interpreter die nicht existierende Variable automatisch als globale Variable.


Datentypen[Bearbeiten]

Da JavaScript keine starke Typisierung aufweist, können in einer Variable alle Arten von Werten gespeichert werden. Der Typ einer Variable richtet sich daher implizit nach dem Typ des darin gespeicherten Wertes. Gegebenenfalls notwendige Typänderungen werden eigenständig im Hintergrund vorgenommen.

Beispiel
// Berechnung Diagonale A4-Papier
var breite    = 210;
var höhe      = 297;
var diagonale = Math.sqrt(breite * breite + höhe * höhe);
var ausgabe   = "Eine A4-Papierseite hat eine Diagonale von " + Math.round(diagonale) + " mm.";

alert(ausgabe);

So ist zum Beispiel die folgende Anweisung in Javascript möglich, ihr Variablentyp ist string; in vielen anderen Programmiersprachen hätte dies eine Fehlermeldung zur Folge.

Beispiel
 5 + "px"

Globale Variablen[Bearbeiten]

Globale Variablen sind im gesamten Dokument gültig und stehen jederzeit zur Verfügung. Wenn innerhalb von Funktionen Variablen ohne ein lokal machendes Schlüsselwort (var, let oder const) deklariert werden, dann sind diese Variablen global. Wird eine var Deklaration außerhalb einer Funktion ausgeführt, erzeugt das ebenfalls eine globale Variable.

Beispiel
var diagonale;
var ausgabe;

berechneDiagonale(210, 297);
ausgabe = "Eine A4-Papierseite hat eine Diagonale von " + diagonale + " mm.";

function berechneDiagonale(breite, höhe)
{
  diagonale = Math.sqrt(breite * breite + höhe * höhe);
  diagonale = Math.round(diagonale);
}
In diesem Beispiel sind die Variablen diagonale und ausgabe global.

Technisch gesehen handelt es sich bei globalen Variablen um Eigenschaften eines Objektes, das die Javascript-Laufzeitumgebung bereitstellt. Dieses Objekt dient als Ausgangspunkt für alle Daten eines Javascript-Programms und wird auch oberstes oder Wurzelobjekt genannt. Wird eine globale Variable erzeugt, wird das Wurzelobjekt automatisch um eine Eigenschaft mit diesem Namen erweitert. Lesen von globalen Variablen ist gleichbedeutend mit einem Zugriff auf die gleichnamige Eigenschaft des Wurzelobjekts.

Man kann das Wurzelobjekt nutzen, um sicherzustellen, auf eine globale Variable diesen Namens zuzugreifen. Bei Javascript im Browser ist dieses Objekt in der globalen Variablen window zu finden. In anderen Umgebungen, wie node.js, kann es z.B. global heißen. Darüber hinaus definieren noch viele Browser die globale Variable self und legen dort eine Referenz auf das globale Objekt ab.

Abzuraten ist von der früher gezeigten Idee, eine Funktion aufzurufen und darin die Kontextvariable this zu verwenden. Neuerer JavaScript-Code sollte immer im strengen Modus (strict mode) geschrieben werden, und darin funktioniert diese Methode nicht mehr.

Beispiel
// Globale Variable
var ausgabe = "Hallo Welt";

// Globale Funktion
function add5(a){return a+5;};

// Abfrage vordefinierter globaler Funktionen. 
alert(alert);
alert(window.alert);
alert(self.alert);

// Abfrage globaler Funktionen
alert(add5);
alert(window.add5);
alert(self.add5);

// Abfrage globaler Variablen
alert(ausgabe);
alert(window.ausgabe);
alert(self.ausgabe);

// Auch möglich aber unsinnig
alert(window.self.ausgabe);
Dieses Beispiel verdeutlicht, das globale Variablen auch gleichzeitig Eigenschaften vom window-Objekt sind.

Lokale Variablen[Bearbeiten]

Lokale Variablen werden innerhalb von Funktionen deklariert. Sie sind nur innerhalb dieser Funktion gültig. Wenn eine Funktion mit Parametern definiert wird, so sind diese Parameter implizit als lokale Variablen definiert und erhalten bei Aufruf automatisch die übergebenen Argumente zugewiesen.

Beispiel
function berechneDiagonale(breite, höhe)
{
  var diagonale = Math.sqrt(breite * breite + höhe * höhe);
  return Math.round(diagonale);
}

var ausgabe = "Eine A4-Papierseite hat eine Diagonale von " + berechneDiagonale(210, 297) + " mm.";
breite, höhe und diagonale sind lokale Variablen in der Funktion berechneDiagonale. Außerhalb der Funktion existiert in diesem Beispiel nur eine globale Variable namens ausgabe.
Beispiel
function berechneWurzel(zahl)
{
  var ergebnis = Math.sqrt(zahl);
  return ergebnis;
}

function berechneDiagonale(breite, höhe)
{
  var diagonale = berechneWurzel(breite * breite + höhe * höhe);
  return Math.round(diagonale);
}
 
var ausgabe = "Eine A4-Papierseite hat eine Diagonale von " + berechneDiagonale(210, 297) + " mm.";
In diesem Beispiel sind zahl und ergebnis lokale Variablen der Funktion berechneWurzel. Sie sind nur innerhalb dieser Funktion sichtbar. Die Variablen breite, höhe und diagonale sind lokale Variablen in der Funktion berechneDiagonale. Im globalen Sichtbarkeitsbereich findet sich nur die Variable ausgabe.
Beispiel
function berechneDiagonale(breite, höhe)
{
  function berechneWurzel()
  {
    var ergebnis = Math.sqrt(breite * breite + höhe * höhe);
    return ergebnis;
  }
 
  var diagonale = berechneWurzel();
  return Math.round(diagonale);
}
 
var ausgabe = "Eine A4-Papierseite hat eine Diagonale von " + berechneDiagonale(210, 297) + " mm.";
In diesem Beispiel wurde die Funktion berechneWurzel innerhalb des Funktionskörpers von berechneDiagonale definiert. Daher sieht die Funktion berechneWurzel auch die lokalen Variablen breite und höhe der Funktion berechneDiagonale und kann somit darauf zugreifen. Die Variable ergebnis bleibt hingegen eine lokale Variable von berechneWurzel und ist auch nur dort sichtbar.

Bei Verwendung geschachtelter Funktionen zeigt es sich, dass Javascript in mehr als nur einem lokalen Kontext nach Variablen sucht. Die Funktion berechneWurzel ist zum einen Träger eines eigenen lokalen Kontextes, ist aber selbst auch Teil des Kontextes von berechneDiagonale und kann darum die lokalen Variablen dieses Kontextes ebenfalls verwenden.

Arbeiten mit Variablen[Bearbeiten]

Der große Vorteil einer Variable ist, dass man ihr etwas zuweisen und damit arbeiten kann. Anstatt also feste Werte im Programm zu verwenden, bezieht man sich auf den Wert, der in einer Variable gespeichert wurde. Hierdurch werden Programme erst flexibel und Funktionen können verallgemeinert werden.

Beispiel
// Fix und nicht flexibel
function berechneDiagonaleVonA4Seite()
{
  return Math.round(Math.sqrt(210 * 210 + 297 * 297));
}

// Flexibel durch Verwendung von Variablen
function berechneDiagonale(breite, höhe)
{
  return Math.round(Math.sqrt(breite * breite + höhe * höhe));
}

var diagonaleVonA4 = berechneDiagonaleVonA4Seite(); // starr
var diagonaleVonA5 = berechneDiagonale(210, 148);   // flexibel und wiederverwendbar
var diagonaleVonA3 = berechneDiagonale(420, 297);   // flexibel und wiederverwendbar

Ein weiterer Vorteil und Nachteil zugleich ist, dass es einer Variable erstmal egal ist, was sie für einen Wert beinhaltet. Dies kann eine Zahl, eine Zeichenkette, ein Array, eine Funktion oder sonstiges Objekt sein. Wenn man hingegen einen bestimmten Typ erwartet, der verarbeitet werden soll, dann muss man unter Umständen zuerst prüfen, ob das Objekt in der Variable kompatibel ist oder konvertiert werden kann.

JavaScript führt eine implizite Typkonvertierung durch, wenn man selber nicht darauf achtet. Kann der Typ für eine bestimmte Operation nicht konvertiert werden, dann wird eine Ausnahme ausgelöst oder es wird ein Standardwert zurückgegeben. Es werden aber auch Funktionen bereitgestellt, um eine explizite Typkonvertierung durchzuführen. Diese geben mehr Kontrolle, wie man auf eine unzureichende Konvertierung reagieren möchte.


Beispiel
var jahrtext = "Wir schreiben das Jahr ";
var jahrzahl = 2012;
var ausgabe  = jahrtext + jahrzahl;

alert(ausgabe); // "Wir schreiben das Jahr 2012"
In diesem Beispiel wird ein numerischer Wert an eine Zeichenkette angehängt.

Scope und Hebung[Bearbeiten]

var ist das klassische Javascript Syntaxelement zum Definieren lokaler Variablen. Die Semantik von var-Variablen unterscheidet sich von der gewohnten Semantik in Sprachen wie C oder Java dahingehend, dass solche Variablen keinen Block-Scope kennen. Was mit var vereinbart wird, wird vom JavaScript-Interpreter so behandelt, als hätte diese Vereinbarung am Beginn des Script-Blocks bzw. der Funktion stattgefunden, worin die var-Deklaration steht. Diese Verschiebung des Deklarationspunktes nennt man Hebung (hoisting).

Beispiel
testVar = "abc";

function test() {
   testVar = 17;
   alert(testVar);     // gibt "17" aus
   if (5 > 1) {
      var testVar = 3;
   }
}

test();
alert(testVar);        // gibt "abc" aus, testVar wurde nicht überschrieben
Die Variable testVar ist lokal zur Funktion test(), weil das Hoisting dafür sorgt, dass die Deklaration aus dem if heraus an den Anfang gezogen wird.

Anders verhält sich let. Dieses Schlüsselwort ist mit ECMAScript2016 eingeführt worden, um die in anderen Sprachen bekannte Scope-Semantik auch in ECMAScript nutzen zu können. Mit let definierte Variablen unterliegen nicht der Hebung, und gelten nur in dem Anweisungsblock, in dem sie definiert wurden.

Empfehlungen für die Praxis[Bearbeiten]

Empfehlung:
  • Verwenden Sie den strict mode, um durch Tippfehler versehentlich erzeugte globale Variablen auszuschließen.
  • Deklarieren Sie globale Variablen am Anfang des Scripts mit var....!
  • Scope (Gültigkeit):
    Benutzen Sie Variablen – soweit möglich – lokal und deklarieren Sie auch dort. So wird ihr Script übersichtlicher und leichter zu debuggen.
  • Halten Sie den globalen Namensraum sauber. Jedes Programm benötigt einen gewissen Stamm an globalen Daten, es ist aber hilfreich, diese nicht in mehreren Variablen zu verteilen. Nutzen Sie statt dessen eine einzige globale Variable und speichern Sie dort ein Namensraum-Objekt. In dessen Eigenschaften können Sie globale Informationen für Ihr Projekt ablegen.
  • Variablennamen
    Benutzen Sie sprechende Namen, d.h. sinnvolle Bezeichnungen, die sich später zurückverfolgen lassen!
    ausgabe = breite * hoehe; ist besser als a = b*h;
  • Beachten Sie die Regeln für selbstvergebene Namen, z.B:
    • Variablen sind case-sensitive, also achten Sie immer auf Groß-und Kleinschreibung.
    • CamelCase
      Besser lesbar ist das so genannte CamelCase, in dem die ersten Buchstaben der einzelnen Bestandteile des Namens groß geschrieben werden.