Javascript Variablen mit let definieren

Variablen mit let statt var – let vs var

Die Deklaration von Variablen mit let löst var, das alte Schlüsselwort für Variablen ab. Variablen, die mit let deklariert werden, gelten nur innerhalb ihres Blocks, während der Gültigkeitsbereich von Variablen mit var auf Funktionen ausgedehnt ist.

var ist zwar komfortabel, aber in großen Projekten ist var schnell eine abgrundtiefe Fehlerquelle.

Variablen mit let statt var

Mit Javascript ES6 ist das Schlüsselwort let aufgetaucht. let ermöglicht eine neue Form des Abkapseln von Variablen und bringt eine Programmierpraxis, die es bislang in Javascript nicht gab: Block Scope – den Gültigkeitsbereich einer Variablen auf einen Block {} beschränken.

Bislang galt in Javascript nur die Beschränkung auf den Gültigkeitsbereich von Funktionen. Variablen, die mit var in einer Funktion angelegt werden, gelten nur innerhalb der Funktion. Das schützt Variablen vor versehentlichem Überschreiben.

Was ist aller Welt ist so schlimm an var, dass wir jetzt let bekommen?

Variablen mit let / var in if-Abfragen

Eine der klassischen Fallen hinter der Definition von Variablen mit var lauert innerhalb einer if-Abfrage.

var condition = false;
function foo(condition) {
   if (condition) {
      var a = 4; // Gültigkeitsbereich von a ist die Funktion foo
      let b = 5; // Gültigkeitsbereich von b ist der Block der if-Abfrage
   }
}

foo(condition);

Ist die Bedingung nicht erfüllt, ist a nach der if-Abfrage undefined und das Ergebnis von Berechnungen, die auf a aufbauen, liefert NaN. Das Skript läuft ohne Warnung munter weiter.

Die mit let deklarierte Variable hingegen führt in jedem Fall nach der if-Abfrage zu einem sofort sichtbaren Syntaxfehler.

for let i=0

Obwohl der Scope oder Gültigkeitsbereich von var hier nicht auf den for-Block beschränkt ist, ist for (var i=0 … ) ein oft genutztes Muster.

for (var i=0; i<10; i++) {
    // ..
}

Mit diesem Muster wollen Programmierer eine Variable nur für einen kleinen abgegrenzten Bereich definierten (und als solche kennzeichnen), auch wenn ihnen bewußt ist, dass var i »nach oben gehoben« wird und oberhalb des for-Blocks gilt. var i signalisiert, dass i tatsächlich nur innerhalb des for-Blocks benutzt werden soll.

Aber wer ist hierauf nicht schon einmal reingefallen?



	
var buttons = document.querySelectorAll("button");
for (var i=0; i<buttons.length; i++) {
    buttons[i].onclick = function() {
        console.log ("Button " + i);
    }
}

Egal welcher Button den Klick abbekommt, die Ausgabe liefert immer dasselbe letzte i der for-Anweisung. Das Event muss als Argument in der anonymen Funktion aufgeführt werden und der angeklickte Button in der Funktion mühsam durch das Event Target identifiziert werden.

Mit for (let i=0 … ) hingegen sagt i, welcher Button geklickt wurde.



	
let buttons = document.querySelectorAll("button");
for (let i=0; i<buttons.length; i++) {
    buttons[i].onclick = function() {
        console.log ("Button " + i);
    }
}

let-Variablen in for-loops werden automatisch getrennt an jede Iteration gebunden.

Das gilt allerdings nicht für IE11. Im Großen und Ganzen unterstützt IE 11 zwar let, aber Variablen werden nicht getrennt an jeden Durchlauf der for-Schleife gebunden.

Hoisting oder Anheben

Anheben oder Hoisting bedeutet, dass die Definition von Variablen automatisch im Hintergrund an den Anfang ihres Scopes gehoben werden, Funktionen automatisch vor ihren ersten Aufruf, damit sie beim Aufruf definiert sind.

// So steht's im Script
foo ();

function foo () {
   var bar = 2; 
   if (bar > 1 | midi) {
      bar nat = bar * 10;
   }
   var midi = (nat * 2) + 2;
   console.log (midi);
}
// So wirkt Hoisting
function foo () {
   var bar, midi, nat; 
   bar = 2;
   if (bar > 1 | midi) {
      bar nat = bar * 10;
   }
   midi = (nat * 2) + 2;
   console.log (midi);
}

foo ();

Mit ECMAScript 6 werden Variablen mit let nicht mehr automatisch an den Anfang des Blocks gehoben.

Wird eine Variable vor ihrer Definition angesprochen, gibt's einen ReferenceError. Die Variable liegt in einem temporalen schwarzen Loch zwischen dem Anfang des Blocks bis die Deklaration ausgeführt wird.

Browser-Support für let

Alle modernen Browser: Chrome ab 41 (Anfang 2015), Firefox ab 39 (Mitte 2015), IE11, Microsoft Edge, Safari ab 11.1 (Herbst 2016). Solange IE 10 auf kommerziellen Seiten nicht unbedingt unterstützt werden muss, kann let die ältere Version der Variablen-Definition mit var ersetzen, um den mächtigen Aufwand für IIFE (Immediately Invoked Function Expression) oder Self Executing Functions an vielen Stellen einsparen.

IE 10 kennt let noch gar nicht, aber Microsoft hat den Support für IE 10 bereits Anfang 2016 eingestellt.

Die immergrünen Browser Chrome, Safari und Firefox machen alleine schon mehr als 75% aller aktiven Browser aus (immergrün: weil ihre Nutzer immer die anfallenden Updates durchführen). Nehmen wir Opera, Edge und IE11 hinzu, bleiben nicht viel mehr als 1 bis 2% der Browser, die ES nicht unterstützen. Die geballte Macht eines Transpilers wie Babel wäre Overkill und wird den Sondermüll des Internet nur künstlich verlängern.

var durch let ersetzen?

Wir sollte aber auch nicht gleich zum Programm-Editor greifen und alle Vorkommen von var durch let ersetzen, denn dabei würden einige fiese kleine Fallen lauern. Die vorangegangenen Beispiele zeigen bereits, dass der Unterschied zwischen let und var mehr mit sich bringt als den Block-Scope.

Kein Problem mit var
var a = 1;
if ( a > 0 ) {
    var panic = 42;
} else {
    var panic = "Immer ein Handtuch dabei haben";
}

console.log ( panic );

würde mit einer einfachen Ersetzung von var durch let einen Syntax-Fehler Can't find variable: panic liefern.

Das Ersetzen von var durch let ist ein Prozess, erfordert erneute Tests und sollte in erster Linie dort ersetzt werden, wo es aus rein stilistischen Gründen eingesetzt wurde (z.B. in for (var i=0) – dabei aber IE11 im Hinterkopf behalten).

var muss auch nicht spurlos aus der Welt verschwinden, sondern kann als Stilmittel eingesetzt werden. let ist angebracht, wo ein eingeschränkter Block-Scope angebracht ist, var zeigt an, dass sich der Gültigkeitsbereich einer Variablen über die gesamte Funktion erstreckt.

function foo () {
	var midi = 42;
	… 
	if (midi > 33) {
		let a = midi * 10;
	}
}

Ah! var midi ist das Signal, dass midi in der gesamten Funktion benötigt wird. let a schafft einen Block-Bereich für einen eingeschränkten Schauplatz des Geschehens.

Ein Stilmittel für diejenigen, die mit Function Scope und Block Scope bereits gut umgehen können.

Kein Polyfill für let?

Nein, es gibt kein Polyfill für let. Javascript Polyfills gibt es für Objekte und Methoden, nicht aber für neue Syntax-Elemente. Um let auch älteren Browsern zugänglich zu machen, muss ein Transpiler – babel.js – eingesetzt werden.

variablen javascript