Bereiche in JavaScript waren schon immer ein heikles Thema, insbesondere im Vergleich zu streng organisierten Sprachen wie C und Java. Viele Jahre lang wurde der Anwendungsbereich von JS nicht besonders ausführlich diskutiert, da die Sprache einfach keine Mittel hatte, die die aktuelle Situation wesentlich beeinflussen würden. In ECMAScript 6 gibt es jedoch einige neue Funktionen, mit denen Entwickler den Umfang von Variablen besser steuern können. Diese Funktionen werden jetzt von Browsern sehr gut unterstützt und sind für die meisten Entwickler gut zugänglich. Neue Schlüsselwörter zum Deklarieren von Variablen unter Berücksichtigung der Tatsache, dass das alte Schlüsselwort
var
nicht verschwunden ist, bedeuten jedoch nicht nur neue Möglichkeiten, sondern auch das Auftreten neuer Fragen. Wann sollten die Schlüsselwörter
let
und
const
? Wie verhalten sie sich? In welchen Situationen ist das Schlüsselwort
var
noch relevant? Das Material, dessen Übersetzung wir heute veröffentlichen, zielt darauf ab, das Problem des Umfangs von Variablen in JavaScript zu untersuchen.

Variable Bereiche: Ein Überblick
Der Umfang einer Variablen ist ein wichtiges Konzept in der Programmierung, das jedoch einige Entwickler, insbesondere Anfänger, verwirren kann. Der Bereich einer Variablen ist der Teil des Programms, in dem auf diese Variable zugegriffen werden kann.
Schauen Sie sich das folgende Beispiel an:
var myVar = 1; function setMyVar() { myVar = 2; } setMyVar(); console.log(myVar);
Was wird die
console.log
Methode ausgeben? Die Antwort auf diese Frage wird niemanden überraschen: Sie wird
2
ausgeben. Die Variable
myVar
außerhalb einer Funktion deklariert, die uns mitteilt, dass sie im globalen Bereich deklariert ist. Daher kann jede im selben Bereich deklarierte Funktion auf
myVar
zugreifen. Wenn es um Code geht, der in einem Browser ausgeführt wird, haben sogar Funktionen, die in anderen mit der Seite verbundenen Dateien deklariert sind, Zugriff auf diese Variable.
Schauen Sie sich nun den folgenden Code an:
function setMyVar() { var myVar = 2; } setMyVar(); console.log(myVar);
Äußerlich sind seine Änderungen im Vergleich zum vorherigen Beispiel unbedeutend. Wir haben nämlich nur die Variablendeklaration in die Funktion eingefügt. Was wird
console.log
jetzt ausgeben? In der Tat nichts, da diese Variable nicht deklariert ist und wenn Sie versuchen, darauf zuzugreifen, wird eine Meldung über einen nicht behandelten
ReferenceError
Fehler angezeigt. Dies geschah, weil die Variable innerhalb der Funktion mit dem Schlüsselwort
var
deklariert wurde. Infolgedessen ist der Bereich dieser Variablen auf den inneren Bereich der Funktion beschränkt. Im Hauptteil dieser Funktion kann darauf zugegriffen werden. Funktionen, die in diese Funktion eingebettet sind, können damit arbeiten, sind jedoch von außen nicht zugänglich. Wenn wir mehrere Funktionen auf derselben Ebene benötigen, um eine bestimmte Variable zu verwenden, müssen wir diese Variable an derselben Stelle deklarieren, an der diese Funktionen deklariert sind, dh eine Ebene höher als ihr interner Bereich.
Hier ist eine interessante Beobachtung: Der Code der meisten Websites und Webanwendungen gilt nicht für die Arbeit eines Programmierers. Die meisten Softwareprojekte sind das Ergebnis der Teamentwicklung und verwenden außerdem Bibliotheken und Frameworks von Drittanbietern. Selbst wenn nur ein Programmierer an der Entwicklung einer Website beteiligt ist, verwendet er normalerweise externe Ressourcen. Aus diesem Grund wird normalerweise nicht empfohlen, Variablen im globalen Bereich zu deklarieren, da Sie nicht im Voraus wissen können, welche Variablen von anderen Entwicklern deklariert werden, deren Code im Projekt verwendet wird. Um dieses Problem zu
umgehen , können Sie einige Tricks anwenden, insbesondere das "
Modul " -Muster und
IIFE, wenn Sie den objektorientierten Ansatz auf die JavaScript-Entwicklung anwenden, obwohl die Kapselung von Daten und Funktionen in gewöhnlichen Objekten den gleichen Effekt erzielen kann. Im Allgemeinen kann festgestellt werden, dass Variablen, deren Umfang über das hinausgeht, was sie benötigen, normalerweise ein Problem darstellen, mit dem etwas getan werden muss.
Var-Schlüsselwortproblem
Also haben wir das Konzept des "Umfangs" herausgefunden. Kommen wir nun zu komplexeren Dingen. Sehen Sie sich den folgenden Code an:
function varTest() { for (var i = 0; i < 3; i++) { console.log(i); } console.log(i); } varTest();
Was wird nach der Ausführung an die Konsole gelangen? Es ist klar, dass die Werte des ansteigenden Zählers
i
:
0
,
1
und
2
innerhalb der Schleife angezeigt werden. Nach dem Ende der Schleife läuft das Programm weiter. Jetzt versuchen wir, auf dieselbe Zählervariable zuzugreifen, die in der
for
Schleife außerhalb dieser Schleife deklariert wurde. Was wird daraus?
Nach dem Aufruf von
i
außerhalb der Schleife gelangt 3 in die Konsole, da das Schlüsselwort
var
auf Funktionsebene wirkt. Wenn Sie eine Variable mit
var
deklarieren, können Sie in einer Funktion darauf zugreifen, auch nachdem Sie die Konstruktion verlassen haben, in der sie deklariert wurde.
Dies kann zu einem Problem werden, wenn Funktionen komplexer werden. Betrachten Sie das folgende Beispiel:
function doSomething() { var myVar = 1; if (true) { var myVar = 2; console.log(myVar); } console.log(myVar); } doSomething();
Was wird jetzt zur Konsole gelangen?
2
und
2
. Wir deklarieren eine Variable, initialisieren sie mit der Nummer 1 und versuchen dann, dieselbe Variable in der
if
neu zu definieren. Da diese beiden Deklarationen im selben Bereich existieren, können wir keine neue Variable mit demselben Namen deklarieren, obwohl wir offensichtlich genau das tun möchten. Infolgedessen wird die erste Variable in der
if
überschrieben.
Dies ist genau der größte Fehler des Schlüsselworts
var
. Der Umfang der damit deklarierten Variablen ist zu groß. Dies kann zu versehentlichem Überschreiben von Daten und anderen Fehlern führen. Große Sichtbereiche führen häufig zu ungenauen Programmen. Im Allgemeinen sollte eine Variable einen Umfang haben, der durch ihre Bedürfnisse begrenzt ist, diese jedoch nicht überschreitet. Es wäre schön, Variablen deklarieren zu können, deren Umfang nicht so groß ist wie bei Verwendung von
var
, was es bei Bedarf ermöglichen würde, stabilere und fehlerfreiere Softwarekonstrukte zu verwenden. Tatsächlich bietet uns ECMAScript 6 solche Möglichkeiten.
Neue Möglichkeiten zum Deklarieren von Variablen
Der ECMAScript 6-Standard (ein neuer Satz von JavaScript-Funktionen, auch bekannt als ES6 und ES2015) bietet zwei neue Möglichkeiten, Variablen zu deklarieren, die sich im Vergleich zu
var
im Umfang unterscheiden und über einige weitere Funktionen verfügen. Dies sind die Schlüsselwörter
let
und
const
. Beide geben uns den sogenannten Blockumfang. Dies bedeutet, dass der Umfang ihrer Verwendung auf einen Codeblock beschränkt werden kann, z. B. eine
for
Schleife oder eine
if
. Dies gibt dem Entwickler mehr Flexibilität bei der Auswahl des Variablenbereichs. Betrachten Sie die neuen Schlüsselwörter.
▍Verwendung des Schlüsselworts let
Das Schlüsselwort
let
ist
var
sehr ähnlich, der Hauptunterschied ist der begrenzte Umfang der damit deklarierten Variablen. Wir schreiben eines der obigen Beispiele neu und ersetzen
var
durch
let
:
function doSomething() { let myVar = 1; if (true) { let myVar = 2; console.log(myVar); } console.log(myVar); } doSomething();
In diesem Fall gelangen die Nummern
2
und
1
zur Konsole. Dies liegt daran, dass die
if
einen neuen Bereich für die mit dem Schlüsselwort
let
deklarierte Variable festlegt. Dies führt dazu, dass die zweite deklarierte Variable eine völlig unabhängige Entität ist, die nicht mit der ersten verwandt ist. Sie können unabhängig voneinander mit ihnen arbeiten. Dies bedeutet jedoch nicht, dass verschachtelte Codeblöcke wie unsere
if
vollständig von Variablen abgeschnitten sind, die mit dem Schlüsselwort
let
in dem Bereich deklariert wurden, in dem sie sich befinden. Sehen Sie sich den folgenden Code an:
function doSomething() { let myVar = 1; if (true) { console.log(myVar); } } doSomething();
In diesem Beispiel erhält die Konsole die Nummer
1
. Der Code in der
if
hat Zugriff auf die Variable, die wir außerhalb erstellt haben. Daher wird der Wert in der Konsole angezeigt. Und was passiert, wenn Sie versuchen, den Bereich zu mischen? Gehen Sie zum Beispiel folgendermaßen vor:
function doSomething() { let myVar = 1; if (true) { console.log(myVar); let myVar = 2; console.log(myVar); } } doSomething();
Es scheint, dass der erste Aufruf von
console.log
1
ausgibt. Wenn Sie jedoch versuchen, diesen Code auszuführen, wird ein
ReferenceError
Fehler
myVar
, der besagt, dass die Variable
myVar
für diesen Bereich nicht definiert oder nicht initialisiert ist (der Text dieses Fehlers unterscheidet sich unterschiedlich Browser). In JavaScript gibt es so etwas wie das Anheben von Variablen an die Spitze ihres Bereichs. Das heißt, wenn eine Variable in einem bestimmten Bereich deklariert wird, reserviert JavaScript einen Platz dafür, noch bevor der Befehl zum Deklarieren ausgeführt wird. Wie genau dies geschieht, ist bei Verwendung von
var
und
let
.
Betrachten Sie das folgende Beispiel:
console.log(varTest); var varTest = 1; console.log(letTest); let letTest = 2;
In beiden Fällen versuchen wir, die Variable zu verwenden, bevor wir sie deklarieren. Konsolenausgabebefehle verhalten sich jedoch anders. Die erste, die eine Variable verwendet, die später mit dem Schlüsselwort
var
deklariert wird, gibt
undefined
- das heißt, was in diese Variable geschrieben wird. Der zweite Befehl, der versucht, auf die Variable zuzugreifen, die später mit dem Schlüsselwort
let
deklariert wird, löst einen
ReferenceError
und teilt uns mit, dass wir versuchen, die Variable zu verwenden, bevor sie deklariert oder initialisiert wird. Was ist los?
Tatsache ist jedoch, dass die für seine Ausführung verantwortlichen Mechanismen vor der Ausführung des Codes diesen Code untersuchen, herausfinden, ob darin Variablen deklariert werden, und sie in diesem Fall unter Vorbehalt von Speicherplatz für sie auslösen. In diesem Fall werden Variablen, die mit dem Schlüsselwort
var
deklariert wurden, innerhalb ihres Gültigkeitsbereichs auf
undefined
initialisiert, selbst wenn auf sie zugegriffen wird, bevor sie deklariert werden. Das Hauptproblem hierbei ist, dass der
undefined
Wert in einer Variablen nicht immer anzeigt, dass sie versuchen, die Variable vor ihrer Deklaration zu verwenden. Schauen Sie sich das folgende Beispiel an:
var var1; console.log(var1); console.log(var2); var var2 = 1;
In diesem Fall
var2
beide Aufrufe von
console.log
undefined
ausgegeben, obwohl
var1
und
var2
unterschiedlich
var2
. Der Punkt hier ist, dass in Variablen, die mit
var
deklariert, aber nicht initialisiert wurden, der
undefined
Wert automatisch geschrieben wird. Gleichzeitig enthalten, wie bereits erwähnt, mit
var
deklarierte Variablen, auf die zugegriffen wird, bevor sie deklariert werden, auch
undefined
. Wenn in einem solchen Code etwas schief geht, ist es daher nicht möglich zu verstehen, was genau die Fehlerquelle ist - unter Verwendung einer nicht initialisierten Variablen oder unter Verwendung einer Variablen vor ihrer Deklaration.
Der Platz für Variablen, die mit dem Schlüsselwort
let
deklariert wurden, ist in ihrem Block reserviert, aber bevor sie deklariert werden, fallen sie in die temporäre Totzone (TDZ, Temporal Dead Zone). Dies führt dazu, dass sie nicht verwendet werden können, bevor sie deklariert wurden, und ein Versuch, auf eine solche Variable zuzugreifen, führt zu einem Fehler. Das System kennt jedoch die Ursache des Problems genau und meldet sie. Dies ist in diesem Beispiel deutlich zu sehen:
let var1; console.log(var1); console.log(var2); let var2 = 1;
Hier wird beim ersten Aufruf von
console.log
undefined
ausgegeben, und beim zweiten Aufruf wird ein
ReferenceError
Fehler ausgegeben, der uns mitteilt, dass die Variable noch nicht deklariert oder initialisiert wurde.
Wenn daher die Verwendung von
var
undefined
erscheint, kennen wir den Grund für dieses Verhalten des Programms nicht. Eine Variable kann entweder deklariert und nicht initialisiert werden oder sie ist möglicherweise noch nicht in diesem Bereich deklariert, sie wird jedoch im Code unter dem Befehl deklariert, um darauf zuzugreifen. Mit dem Schlüsselwort
let
können wir verstehen, was genau passiert, was für das Debuggen viel nützlicher ist.
▍Verwendung des Schlüsselworts const
Das
const
Schlüsselwort ist
let
sehr ähnlich, aber sie haben einen wichtigen Unterschied. Dieses Schlüsselwort wird verwendet, um Konstanten zu deklarieren. Die Werte der Konstanten können nach ihrer Initialisierung nicht mehr geändert werden. Es ist zu beachten, dass dies nur für Werte primitiver Typen, Wasser, Zeichenfolgen oder Zahlen gilt. Wenn die Konstante etwas Komplexeres ist, z. B. ein Objekt oder ein Array, kann die interne Struktur einer solchen Entität geändert werden. Sie können sie nicht einfach durch eine andere ersetzen. Sehen Sie sich den folgenden Code an:
let mutableVar = 1; const immutableVar = 2; mutableVar = 3; immutableVar = 4;
Dieser Code wird bis zur letzten Zeile ausgeführt. Der Versuch, einer Konstanten einen neuen Wert zuzuweisen, führt zu einem
TypeError
Fehler. So verhalten sich Konstanten, aber wie bereits erwähnt, können die Objekte, die Konstanten initialisieren, geändert werden, sie können Mutationen unterliegen, was zu
Überraschungen führen kann.
Vielleicht fragen Sie sich als JavaScript-Entwickler, warum die Immunität von Variablen wichtig ist. Konstanten sind ein neues Phänomen in JavaScript, während sie ein wesentlicher Bestandteil von Sprachen wie C oder Java sind. Warum ist dieses Konzept so beliebt? Tatsache ist, dass wir durch die Verwendung von Konstanten darüber nachdenken, wie unser Code funktioniert. In einigen Situationen kann das Ändern des Werts einer Variablen den Code stören, z. B. wenn die Nummer Pi darin geschrieben ist und ständig darauf zugegriffen wird oder wenn die Variable einen Link zu einem HTML-Element enthält, mit dem Sie ständig arbeiten müssen. Angenommen, hier ist eine Konstante, in die ein Link zu einer bestimmten Schaltfläche geschrieben ist:
const myButton = document.querySelector('#my-button');
Wenn der Code vom Link zum HTML-Element abhängt, müssen wir die Unveränderlichkeit dieses Links sicherstellen. Infolgedessen können wir sagen, dass das Schlüsselwort
const
nicht nur den Weg der Verbesserungen im Bereich der Sichtbarkeit einschlägt, sondern auch die Möglichkeit einschränkt, die Werte von Konstanten zu ändern, die mit diesem Schlüsselwort deklariert wurden. Denken Sie daran, wie wir gesagt haben, dass eine Variable genau den Umfang haben sollte, den sie benötigt. Diese Idee kann fortgesetzt werden, indem eine Empfehlung abgegeben wird, wonach eine Variable nur die Fähigkeit haben sollte, sich zu ändern, was für eine ordnungsgemäße Arbeit damit erforderlich ist, und nicht mehr.
Hier ist gutes Material zum Thema Immunität, aus dem eine wichtige Schlussfolgerung gezogen werden kann, wonach die Verwendung unveränderlicher Variablen uns dazu bringt, genauer über unseren Code nachzudenken, was zu einer Verbesserung der Reinheit des Codes und zu einer Verringerung der Anzahl unangenehmer Überraschungen führt, die sich aus seiner Funktionsweise ergeben.
Als ich anfing, die Schlüsselwörter
let
und
const
, habe ich im Grunde genommen
let
und nur dann auf
const
, wenn ein neuer Wert in eine mit
let
deklarierte Variable geschrieben wurde
let
die dem Programm schaden könnte. Aber als ich mehr über das Programmieren lernte, überlegte ich es mir anders. Jetzt ist mein Hauptwerkzeug
const
und ich kann es nur verwenden, wenn der Wert der Variablen neu geschrieben werden muss. Dies lässt mich darüber nachdenken, ob es wirklich notwendig ist, den Wert einer bestimmten Variablen zu ändern. In den meisten Fällen ist dies nicht erforderlich.
Benötigen wir das Schlüsselwort var?
Die Schlüsselwörter
let
und
const
tragen zu einem verantwortungsbewussteren Programmieransatz bei. Gibt es Situationen, in denen das Schlüsselwort
var
noch benötigt wird? Ja gibt es. Es gibt verschiedene Situationen, in denen dieses Schlüsselwort für uns immer noch nützlich ist. Überlegen Sie genau, worüber wir sprechen, bevor Sie
var
in
let
oder
const
ändern.
▍ Unterstützungsstufe für verschiedene Schlüsselwörter durch Browser
Mit dem Schlüsselwort
var
deklarierte Variablen haben eine sehr wichtige Funktion, die
let
und
const
fehlt. Wir sprechen nämlich von der Tatsache, dass absolut alle Browser dieses Schlüsselwort unterstützen. Obwohl die Unterstützung für
let und
const durch Browser sehr gut ist, besteht das Risiko, dass Ihr Programm in einem Browser landet, der sie nicht unterstützt. Um die Konsequenzen eines solchen Vorfalls zu verstehen, müssen Sie überlegen, wie Browser mit nicht unterstütztem JavaScript-Code umgehen und nicht wie sie beispielsweise auf CSS-Code reagieren, den sie nicht verstehen.
Wenn der Browser einige CSS-Funktionen nicht unterstützt, führt dies im Grunde zu einer gewissen Verzerrung der Anzeige auf dem Bildschirm. Eine Site in einem Browser, die keinen der von der Site verwendeten Stile unterstützt, sieht nicht wie erwartet aus, kann aber sehr wahrscheinlich verwendet werden. Wenn Sie beispielsweise
let
und der Browser dieses Schlüsselwort nicht unterstützt, funktioniert Ihr JS-Code dort einfach nicht. Es wird nicht sein - das ist alles. Angesichts der Tatsache, dass JavaScript eine der wichtigsten Komponenten des modernen Webs ist, kann dies zu einem ernsthaften Problem werden, wenn Ihre Programme in veralteten Browsern funktionieren müssen.
Wenn Leute über die Browserunterstützung für Websites sprechen, fragen sie normalerweise, in welchem Browser die Website optimal funktioniert. Wenn es sich um eine Site handelt, deren Funktionalität auf der Verwendung von
let
und
const
basiert, muss eine ähnliche Frage anders gestellt werden: „In welchen Browsern funktioniert unsere Site nicht?“. Und das ist viel ernster, als darüber zu sprechen, ob
display: flex
oder nicht. Bei den meisten Websites ist die Anzahl der Benutzer mit veralteten Browsern nicht groß genug, um sich Sorgen zu machen. Wenn es sich jedoch um einen Online-Shop oder um Websites handelt, deren Eigentümer Werbung kaufen, kann dies eine sehr wichtige Überlegung sein. Bevor Sie in solchen Projekten neue Chancen nutzen, sollten Sie das Risikoniveau bewerten.
Wenn Sie wirklich alte Browser unterstützen müssen, aber
let
,
const
und andere neue ES6-Funktionen verwenden möchten, besteht eine der Lösungen für dieses Problem darin, einen JavaScript-Transporter wie
Babel zu verwenden . Transpiler bieten die Übersetzung von neuem Code in das, was alte Browser verstehen. Mit Babel können Sie modernen Code schreiben, der die neuesten Funktionen der Sprache verwendet, und ihn dann in Code konvertieren, den ältere Browser ausführen können.
, ? , . , , , , . , . , , . ES6-, Babel, Babel , , . , , . . ? - IE8 ? , , , , , .
▍ var
,
var
, . . :
var myVar = 1; function myFunction() { var myVar = 2;
,
myVar
, , . , . , , , , . , .
var
.
var myVar = 1; function myFunction() { var myVar = 2; console.log(myVar);
var
,
window
.
let
const
. , JS- , (, , ) , .
, . , . , , , :
let myGlobalVars = {}; let myVar = 1; myGlobalVars.myVar = myVar; function myFunction() { let myVar = 2; console.log(myVar);
, , , , . , ,
var
, , , , , .
Zusammenfassung
, ? ? :
- IE10 - ? —
var
. - JavaScript, , ,
var
, const
. - (, , ) — let
.
let
const
, ECMAScript 6, ( ) - -. , , , . , - , «» «» , ,
let
const
, .
! ,
const
var
,
let
, , , ?
