ECMAScript 6 führte die let
Erklärung ein .
Ich habe gehört, dass es als "lokale" Variable beschrieben wird, bin mir aber immer noch nicht ganz sicher, wie es sich anders verhält als das var
Schlüsselwort.
Was sind die Unterschiede? Wann sollte let
über verwendet werden var
?
let
ist im Entwurf der 6. Ausgabe enthalten und wird höchstwahrscheinlich in der endgültigen Spezifikation enthalten sein.Antworten:
Geltungsbereich Regeln
Der Hauptunterschied besteht in den Geltungsbereichsregeln. Variablen, die durch das
var
Schlüsselwort deklariert werden, werden auf den unmittelbaren Funktionskörper (daher den Funktionsumfang) beschränkt, währendlet
Variablen auf den unmittelbaren umschließenden Block, der mit bezeichnet wird{ }
(daher der Blockumfang).Der Grund, warum das
let
Schlüsselwort in die Sprache eingeführt wurde, war der Funktionsumfang, der verwirrend ist und eine der Hauptursachen für Fehler in JavaScript war.Schauen Sie sich dieses Beispiel aus einer anderen Frage zum Stapelüberlauf an :
My value: 3
wurde bei jedemfuncs[j]();
Aufruf an die Konsole ausgegeben, da anonyme Funktionen an dieselbe Variable gebunden waren.Die Leute mussten sofort aufgerufene Funktionen erstellen, um den korrekten Wert aus den Schleifen zu erfassen, aber das war auch haarig.
Heben
Während Variablen, die mit dem
var
Schlüsselwort deklariert wurden, gehisst (initialisiert mit,undefined
bevor der Code ausgeführt wird), bedeutet dies, dass sie in ihrem umschließenden Bereich bereits zugänglich sind, bevor sie deklariert werden:let
Variablen werden erst initialisiert, wenn ihre Definition ausgewertet ist. Der Zugriff auf sie vor der Initialisierung führt zu aReferenceError
. Die Variable soll sich vom Beginn des Blocks bis zur Verarbeitung der Initialisierung in der "zeitlichen Totzone" befinden.Globale Objekteigenschaft erstellen
Auf der obersten Ebene wird
let
im Gegensatz dazuvar
keine Eigenschaft für das globale Objekt erstellt:Neuerklärung
Im strengen Modus können
var
Sie dieselbe Variable im selben Bereich erneut deklarieren, währendlet
ein SyntaxError ausgelöst wird.quelle
let
Blockausdrucklet (variable declaration) statement
ist nicht Standard und wird in Zukunft entfernt, bugzilla.mozilla.org/show_bug.cgi?id=1023609 .let
kann auch verwendet werden, um Probleme mit Verschlüssen zu vermeiden. Es bindet einen neuen Wert, anstatt eine alte Referenz beizubehalten, wie in den folgenden Beispielen gezeigt.Der obige Code zeigt ein klassisches JavaScript-Schließproblem. Der Verweis auf die
i
Variable wird im Click-Handler-Closure gespeichert und nicht der tatsächliche Wert voni
.Jeder einzelne Klick-Handler verweist auf dasselbe Objekt, da es nur ein Zählerobjekt gibt, das 6 enthält, sodass Sie bei jedem Klick sechs erhalten.
Eine allgemeine Problemumgehung besteht darin, dies in eine anonyme Funktion zu packen und
i
als Argument zu übergeben. Solche Probleme können jetzt auch vermieden werden, indemlet
stattdessenvar
wie im folgenden Code gezeigt verwendet wird.(Getestet in Chrome und Firefox 50)
quelle
let
, aber es warnt "6" für alle Schaltflächen. Haben Sie eine Quelle, die sagt, wielet
man sich verhalten soll?let
dies wirklich nützlich wäre. Das Festlegen von Ereignis-Listenern in einer Schleife erfordert keinen sofort aufgerufenen Funktionsausdruck mehr für das lokale Scopingi
bei jeder Iteration.Was ist der Unterschied zwischen
let
undvar
?var
Anweisung definierte Variable ist in der gesamten Funktion, in der sie definiert ist, vom Beginn der Funktion an bekannt. (*)let
Anweisung definierte Variable ist ab dem Zeitpunkt ihrer Definition nur in dem Block bekannt, in dem sie definiert ist. (**)Beachten Sie den folgenden Code, um den Unterschied zu verstehen:
Hier können wir sehen, dass unsere Variable
j
nur in der ersten for-Schleife bekannt ist, nicht jedoch vorher und nachher. Unsere Variablei
ist jedoch in der gesamten Funktion bekannt.Beachten Sie auch, dass Variablen mit Blockbereich nicht bekannt sind, bevor sie deklariert werden, da sie nicht angehoben werden. Sie dürfen auch nicht dieselbe Variable mit Blockbereich innerhalb desselben Blocks neu deklarieren. Dies macht Variablen mit Blockbereich weniger fehleranfällig als Variablen mit globalem oder funktionalem Bereich, die angehoben werden und bei mehreren Deklarationen keine Fehler verursachen.
Ist es heute sicher zu benutzen
let
?Einige Leute würden argumentieren, dass wir in Zukunft NUR let-Anweisungen verwenden werden und dass var-Anweisungen veraltet sein werden. Der JavaScript-Guru Kyle Simpson hat einen sehr ausführlichen Artikel darüber geschrieben, warum er glaubt, dass dies nicht der Fall sein wird .
Heute ist dies jedoch definitiv nicht der Fall. Tatsächlich müssen wir uns fragen, ob es sicher ist, die
let
Aussage zu verwenden. Die Antwort auf diese Frage hängt von Ihrer Umgebung ab:Wenn Sie serverseitigen JavaScript-Code ( Node.js ) schreiben , können Sie die
let
Anweisung sicher verwenden .Wenn Sie clientseitigen JavaScript-Code schreiben und einen browserbasierten Transpiler (wie Traceur oder babel-standalone ) verwenden, können Sie die
let
Anweisung sicher verwenden. Ihr Code ist jedoch in Bezug auf die Leistung wahrscheinlich alles andere als optimal.Wenn Sie clientseitigen JavaScript-Code schreiben und einen knotenbasierten Transpiler verwenden (wie das Traceur-Shell-Skript oder Babel ), können Sie die
let
Anweisung sicher verwenden . Und da Ihr Browser nur über den transpilierten Code Bescheid weiß, sollten die Leistungsnachteile begrenzt sein.Wenn Sie clientseitigen JavaScript-Code schreiben und keinen Transpiler verwenden, müssen Sie die Browserunterstützung in Betracht ziehen.
Es gibt noch einige Browser, die überhaupt nicht unterstützen
let
:So behalten Sie den Überblick über die Browserunterstützung
Auf dieser Seite finden Sie eine aktuelle Übersicht darüber, welche Browser die
let
Aussage zum Zeitpunkt des Lesens dieser Antwort unterstützen .Can I Use
(*) Global und funktional scoped Variablen initialisiert und verwendet werden , bevor sie deklariert werden , da JavaScript - Variablen werden gehisst . Dies bedeutet, dass Deklarationen immer ganz oben im Geltungsbereich stehen.
(**) Variablen mit Blockbereich werden nicht angehoben
quelle
i
Ist überall im Funktionsblock bekannt! Es beginnt alsundefined
(aufgrund des Hebens), bis Sie einen Wert zuweisen! ps:let
wird ebenfalls hochgezogen (an die Spitze des Blocks), gibt jedoch ein Zeichen,ReferenceError
wenn im Block vor der ersten Zuweisung darauf verwiesen wird. (ps2: Ich bin ein Pro-Semikolon-Typ, aber nach einem Block brauchst du wirklich kein Semikolon). Trotzdem danke, dass Sie den Reality-Check bezüglich Support hinzugefügt haben!let
und verdeutlichen sollenvar
!let
undconst
wurde empfohlen, es nur zu verwenden, wenn Sie tatsächlich ihre zusätzlichen Funktionen benötigen , da das Erzwingen / Überprüfen dieser zusätzlichen Funktionen (wie z. B. Nur-Schreiben-Konstante) zu mehr Arbeit führt '(und zusätzliche Scope-Knoten im Scope-Baum) für die (aktuelle) Engine (s) zum Erzwingen / Überprüfen / Überprüfen / Einrichten.Hier ist eine Erklärung des
let
Schlüsselworts mit einigen Beispielen.Diese Tabelle auf Wikipedia zeigt, welche Browser Javascript 1.7 unterstützen.
Beachten Sie, dass dies nur von Mozilla- und Chrome-Browsern unterstützt wird. IE, Safari und möglicherweise andere nicht.
quelle
let
msdn.microsoft.com/en-us/library/ie/dn342892%28v=vs.85%29.aspxDer akzeptierten Antwort fehlt ein Punkt:
quelle
for
Schleifeninitialisierer, was den Anwendungsbereich der Einschränkungen von dramatisch einschränktelet
. Upvoted.let
Bereich blockieren
Mit dem
let
Schlüsselwort deklarierte Variablen haben einen Blockumfang. Dies bedeutet, dass sie nur in dem Block verfügbar sind , in dem sie deklariert wurden.Auf der obersten Ebene (außerhalb einer Funktion)
Auf der obersten Ebene
let
erstellen mit deklarierte Variablen keine Eigenschaften für das globale Objekt.Innerhalb einer Funktion
Innerhalb einer Funktion (aber außerhalb eines Blocks)
let
hat der gleiche Umfang wievar
.In einem Block
Auf Variablen, die
let
innerhalb eines Blocks deklariert wurden, kann außerhalb dieses Blocks nicht zugegriffen werden.In einer Schleife
Mit
let
in Schleifen deklarierte Variablen können nur innerhalb dieser Schleife referenziert werden.Schleifen mit Verschlüssen
Wenn Sie
let
anstellevar
einer Schleife verwenden, erhalten Sie mit jeder Iteration eine neue Variable. Das bedeutet, dass Sie einen Verschluss sicher in einer Schleife verwenden können.Zeitliche Totzone
Aufgrund der zeitlichen Totzone kann auf Variablen, die mit deklariert wurden,
let
nicht zugegriffen werden, bevor sie deklariert wurden. Der Versuch, dies zu tun, löst einen Fehler aus.Keine erneute Erklärung
Sie können dieselbe Variable nicht mehrmals mit deklarieren
let
. Sie können eine Variable auch nichtlet
mit demselben Bezeichner deklarieren wie eine andere Variable, die mit deklariert wurdevar
.const
const
ist ziemlich ähnlich zulet
- es hat einen Blockumfang und hat TDZ. Es gibt jedoch zwei Dinge, die unterschiedlich sind.Keine Neuzuweisung
Mit deklarierte Variable
const
kann nicht neu zugewiesen werden.Beachten Sie, dass dies nicht bedeutet, dass der Wert unveränderlich ist. Seine Eigenschaften können noch geändert werden.
Wenn Sie ein unveränderliches Objekt haben möchten, sollten Sie verwenden
Object.freeze()
.Initializer ist erforderlich
Sie müssen immer einen Wert angeben, wenn Sie eine Variable mit deklarieren
const
.quelle
Hier ist ein Beispiel für den Unterschied zwischen den beiden (Unterstützung für Chrom wurde gerade gestartet):
Wie Sie sehen, hat die
var j
Variable immer noch einen Wert außerhalb des for-Schleifenbereichs (Block Scope), aber dielet i
Variable ist außerhalb des for-Schleifenbereichs undefiniert.quelle
Es gibt einige subtile Unterschiede - das
let
Scoping verhält sich eher wie das variable Scoping in mehr oder weniger anderen Sprachen.zB Es erstreckt sich auf den umschließenden Block. Sie existieren nicht, bevor sie deklariert wurden usw.
Es ist jedoch erwähnenswert, dass dies
let
nur ein Teil neuerer Javascript-Implementierungen ist und unterschiedliche Grade an Browserunterstützung bietet .quelle
let
im Entwurf der 6. Ausgabe enthalten ist und höchstwahrscheinlich in der endgültigen Spezifikation enthalten sein wird.let
. Safari, IE und Chome tun dies nicht.let
dass Sie keine Variable verwenden, die durch einelet
am oberen Rand Ihres Blocks definierte Variable definiert ist . Wenn Sie eineif
Anweisung haben, die mehr als nur ein paar Codezeilen umfasst, können Sie vergessen, dass Sie diese Variable erst verwenden können, nachdem sie definiert wurde. Toller Punkt !!!let
wird die Variable an den Anfang des Blocks gehoben. Wenn Sie jedoch auf die Variable im Block vor der Variablendeklaration verweisen, wird ein ReferenceError angezeigt (mein Hinweis: anstelle von good oldundefined
) Die Variable befindet sich vom Beginn des Blocks bis zur Verarbeitung der Deklaration in einer 'zeitlichen Totzone'. " Gleiches gilt für "switch-Anweisungen, da nur ein Block zugrunde liegt". Quelle: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Der Hauptunterschied ist der Bereichsunterschied , während let nur innerhalb des deklarierten Bereichs verfügbar sein kann , wie z. B. in for-Schleife. Auf var kann beispielsweise außerhalb der Schleife zugegriffen werden. Aus der Dokumentation in MDN (Beispiele auch aus MDN):
Vergessen Sie auch nicht, dass es sich um eine ECMA6-Funktion handelt, die noch nicht vollständig unterstützt wird. Daher ist es besser, sie immer mit Babel usw. auf ECMA5 zu übertragen, um weitere Informationen zum Besuch der Babel-Website zu erhalten
quelle
Variable nicht hebenlet
wird nicht auf den gesamten Umfang des Blocks angehoben, in dem sie erscheinen. Im Gegensatz dazuvar
könnte wie folgt angehoben werden.Eigentlich Per @Bergi, Beide
var
undlet
werden gehisst .Müllabfuhr
Der Blockumfang von
let
ist nützlich für Verschlüsse und Speicherbereinigung, um Speicher zurückzugewinnen. Erwägen,Der
click
Handler-Rückruf benötigt diehugeData
Variable überhaupt nicht. Theoretisch könnteprocess(..)
die riesige Datenstruktur nach LäufenhugeData
durch Müll gesammelt werden. Es ist jedoch möglich, dass einige JS-Engines diese riesige Struktur beibehalten müssen, da dieclick
Funktion über den gesamten Bereich geschlossen ist.Der Blockumfang kann jedoch dazu führen, dass diese riesige Datenstruktur zum gesammelten Müll wird.
let
Schleifenlet
in der Schleife kann es erneut an jede Iteration der Schleife binden , wobei sichergestellt wird, dass der Wert vom Ende der vorherigen Schleifeniteration neu zugewiesen wird. Erwägen,Ersetzen Sie jedoch
var
durchlet
Da Sie
let
eine neue lexikalische Umgebung mit diesen Namen für a) den Initialisiererausdruck b) jede Iteration (vor der Auswertung des Inkrementausdrucks) erstellen, finden Sie hier weitere Details .quelle
Hier ist ein Beispiel, um das zu ergänzen, was andere bereits geschrieben haben. Angenommen, Sie möchten ein Array von Funktionen erstellen
adderFunctions
, wobei jede Funktion ein einzelnes Number-Argument verwendet und die Summe des Arguments und des Funktionsindex im Array zurückgibt. Der Versuch,adderFunctions
mit einer Schleife mithilfe desvar
Schlüsselworts zu generieren, funktioniert nicht so, wie es jemand naiv erwartet:Der obige Prozess generiert nicht das gewünschte Funktionsarray, da
i
der Gültigkeitsbereich über die Iteration desfor
Blocks hinausgeht , in dem jede Funktion erstellt wurde. Stattdesseni
bezieht sich der Abschluss in jeder Funktioni
am Ende der Schleife auf den Wert am Ende der Schleife (1000) für jede anonyme Funktion inadderFunctions
. Das wollten wir überhaupt nicht: Wir haben jetzt ein Array von 1000 verschiedenen Funktionen im Speicher mit genau dem gleichen Verhalten. Und wenn wir anschließend den Wert von aktualisiereni
, wirkt sich die Mutation auf alle ausadderFunctions
.Wir können es jedoch erneut mit dem
let
Schlüsselwort versuchen :Dieses Mal
i
wird bei jeder Iteration derfor
Schleife zurückgebunden. Jede Funktion behält jetzt den Wert voni
zum Zeitpunkt der Erstellung der Funktion bei undadderFunctions
verhält sich wie erwartet.Wenn Sie nun die beiden Verhaltensweisen mischen, werden Sie wahrscheinlich sehen, warum es nicht empfohlen wird, die neueren
let
undconst
die älterenvar
im selben Skript zu mischen . Dies kann zu einem spektakulär verwirrenden Code führen.Lass dir das nicht passieren. Verwenden Sie einen Linter.
quelle
let value = i;
. Diefor
Anweisung erstellt einen lexikalischen Block.Der Unterschied liegt im Umfang der mit jedem deklarierten Variablen.
In der Praxis gibt es eine Reihe nützlicher Konsequenzen des unterschiedlichen Umfangs:
let
Variablen sind nur im nächsten umschließenden Block ({ ... }
) sichtbar .let
Variablen können nur in Codezeilen verwendet werden, die nach der Deklaration der Variablen auftreten (obwohl sie angehoben werden !).let
Variablen dürfen nicht durch ein nachfolgendesvar
oder neu deklariert werdenlet
.let
Variablen werden dem globalenwindow
Objekt nicht hinzugefügt .let
Variablen sind bei Schließungen einfach zu verwenden (sie verursachen keine Rennbedingungen ).Die durch
let
die Einschränkung der Sichtbarkeit der Variablen auferlegten Einschränkungen erhöhen die Wahrscheinlichkeit, dass unerwartete Namenskollisionen frühzeitig erkannt werden. Dies erleichtert das Verfolgen und Überlegen von Variablen, einschließlich ihrer Erreichbarkeit (was bei der Rückgewinnung nicht verwendeten Speichers hilft).Folglich ist
let
es weniger wahrscheinlich, dass Variablen Probleme verursachen, wenn sie in großen Programmen verwendet werden oder wenn unabhängig entwickelte Frameworks auf neue und unerwartete Weise kombiniert werden.var
Dies kann dennoch nützlich sein, wenn Sie sicher sind, dass Sie den Einzelbindungseffekt wünschen, wenn Sie einen Abschluss in einer Schleife verwenden (Nr. 5) oder wenn Sie extern sichtbare globale Variablen in Ihrem Code deklarieren (Nr. 4). Die Verwendungvar
für den Export kann ersetzt werden, wennexport
der Transpiler-Speicherplatz in die Kernsprache migriert wird.Beispiele
1. Keine Verwendung außerhalb des nächstgelegenen umschließenden Blocks: Dieser Codeblock gibt einen Referenzfehler aus, da die zweite Verwendung
x
außerhalb des Blocks erfolgt, in dem er deklariert ist mitlet
:Im Gegensatz dazu
var
funktioniert das gleiche Beispiel mit .2. Keine Verwendung vor der Deklaration:
Dieser Codeblock löst ein aus,
ReferenceError
bevor der Code ausgeführt werden kann, da er verwendetx
wird, bevor er deklariert wird:Im Gegensatz dazu
var
analysiert und läuft das gleiche Beispiel ohne Ausnahmen.3. Keine erneute Deklaration: Der folgende Code zeigt, dass eine mit deklarierte Variable
let
möglicherweise später nicht erneut deklariert wird:4. Globals, die nicht an Folgendes gebunden sind
window
:5. Einfache Verwendung mit Verschlüssen: Mit deklarierte Variablen
var
funktionieren nicht gut mit Verschlüssen in Schleifen. Hier ist eine einfache Schleife, die die Folge von Werten ausgibt, die die Variablei
zu verschiedenen Zeitpunkten hat:Im Einzelnen gibt dies Folgendes aus:
In JavaScript verwenden wir Variablen häufig zu einem wesentlich späteren Zeitpunkt als beim Erstellen. Wenn wir dies demonstrieren, indem wir die Ausgabe mit einem an Folgendes übergebenen Abschluss verzögern
setTimeout
:... die Ausgabe bleibt unverändert, solange wir dabei bleiben
let
. Im Gegensatz dazu, wenn wirvar i
stattdessen verwendet hätten:... die Schleife gibt unerwartet fünfmal "i is 5" aus:
quelle
var
anstelle von verwendenlet
, entspricht der Code:var i = 0; while (i < 5) { doSomethingLater(); i++; }
i
Befindet sich außerhalb des Abschlusses und zum Zeitpunkt derdoSomethingLater()
Ausführungi
bereits fünfmal inkrementiert, die Ausgabei is 5
fünfmal erfolgt. Bei Verwendunglet
befindet sich die Variablei
innerhalb des Abschlusses, sodass jeder asynchrone Aufruf eine eigene Kopie erhält,i
anstatt die 'globale' zu verwenden, mit der erstellt wurdevar
.for
. Eine genauere Transformation ist zwar komplizierter, aber das klassischefor (var i = 0; i < 5; i++) { (function(j) { setTimeout(_ => console.log(
i ist $ {j},), 125/*ms*/); })(i); }
das einen "Funktionsaktivierungsdatensatz" einführt, um jeden Wert voni
mit dem Namenj
innerhalb der Funktion zu speichern .Mögen die folgenden zwei Funktionen den Unterschied zeigen:
quelle
let
ist interessant, weil es uns erlaubt, so etwas zu tun:Was zur Zählung führt [0, 7].
Wohingegen
Zählt nur [0, 1].
quelle
Funktion VS Blockumfang:
Der wesentliche Unterschied zwischen
var
undlet
ist , dass die deklarierten Variablen mitvar
ist Funktion scoped . Während Funktionen erklärt mitlet
sind Block scoped . Zum Beispiel:Variablen mit
var
:Wenn die erste Funktion
testVar
aufgerufen wird, ist die mit deklarierte Variable foovar
außerhalb derif
Anweisung weiterhin verfügbar . Diese Variablefoo
wäre im Rahmen der Funktion überall verfügbar .testVar
Variablen mit
let
:Wenn die zweite Funktion
testLet
aufgerufen wird, ist die mit deklarierte Variablenleistelet
nur innerhalb derif
Anweisung zugänglich . Da mit Variablen deklariertlet
wird Block scoped (wobei ein Block ist der Code zwischen geschweiften Klammern zif{}
,for{}
,function{}
).let
Variablen werden nicht gehisst:Ein weiterer Unterschied zwischen
var
undlet
besteht darin, dass Variablen mit deklariert mitlet
nicht angehoben werden . Ein Beispiel ist der beste Weg, um dieses Verhalten zu veranschaulichen:Variablen mit werden
let
nicht gehisst:Variablen mit
var
do get hochgezogen:Global
let
hängt nicht daranwindow
:Eine
let
im globalen Bereich mit deklarierte Variable (dies ist Code, der nicht in einer Funktion enthalten ist) wird nicht als Eigenschaft für das globalewindow
Objekt hinzugefügt . Zum Beispiel (dieser Code befindet sich im globalen Bereich):Verwenden
let
Sie es,var
wann immer Sie können, da es einfach spezifischer ist. Dies reduziert mögliche Namenskonflikte, die beim Umgang mit einer großen Anzahl von Variablen auftreten können.var
kann verwendet werden, wenn eine globale Variable explizit imwindow
Objekt enthalten sein soll (immer sorgfältig prüfen, ob dies wirklich erforderlich ist).quelle
Es scheint auch, dass "var" zumindest in Visual Studio 2015, TypeScript 1.5, mehrere Deklarationen desselben Variablennamens in einem Block zulässt und "let" nicht.
Dies erzeugt keinen Kompilierungsfehler:
Dieser Wille:
quelle
var
ist eine Variable für den globalen Bereich (anhebbar).let
undconst
ist Blockumfang.quelle
Beim Benutzen
let
Das
let
Schlüsselwort hängt die Variablendeklaration an den Gültigkeitsbereich des Blocks (üblicherweise eines{ .. }
Paares) an, in dem es enthalten ist. Mit anderen Worten, eslet
übernimmt implizit den Gültigkeitsbereich eines Blocks für seine Variablendeklaration.let
Auf Variablen kann imwindow
Objekt nicht zugegriffen werden, da auf sie nicht global zugegriffen werden kann.Beim Benutzen
var
var
und Variablen in ES5 haben Bereiche in Funktionen, was bedeutet, dass die Variablen innerhalb der Funktion und nicht außerhalb der Funktion selbst gültig sind.var
Auf Variablen kann imwindow
Objekt zugegriffen werden, da auf sie nicht global zugegriffen werden kann.Wenn Sie mehr wissen möchten, lesen Sie weiter unten
Eine der bekanntesten Interviewfragen zum Umfang kann auch die genaue Verwendung von
let
undvar
wie folgt genügen .Beim Benutzen
let
Dies liegt daran, wenn bei der Verwendung
let
für jede Schleifeniteration die Variable einen Gültigkeitsbereich hat und eine eigene Kopie hat.Beim Benutzen
var
Dies liegt daran, dass bei Verwendung
var
für jede Schleifeniteration die Variable einen Gültigkeitsbereich hat und eine gemeinsam genutzte Kopie hat.quelle
In den meisten grundlegenden Begriffen,
⚡️ Sandbox zum Herumspielen ↓
quelle
Wenn ich die Spezifikationen richtig lese, kann ich
let
dankenswerterweise auch nutzen, um selbstaufrufende Funktionen zu vermeiden , mit denen nur private Mitglieder simuliert werden - ein beliebtes Entwurfsmuster, das die Lesbarkeit des Codes verringert, das Debuggen erschwert, keinen echten Codeschutz oder andere Vorteile bietet - außer möglicherweise die Zufriedenheit anderer Wunsch nach Semantik, also hör auf, sie zu benutzen. /schimpfenSiehe ' Emulieren privater Schnittstellen '
quelle
let
dies auch tun ? (Ich nehme an, Sie meinen IIFE mit "selbstaufrufender Funktion".)hiddenProperty
im Konstruktor? Es gibt nur einehiddenProperty
für alle Instanzen in Ihrer „Klasse“.Einige Hacks mit
let
:1.
2.
3.
Getter und Setter mit
let
:quelle
let { type, name, value } = node;
? Sie erstellen ein neues Objekt mit 3 Eigenschaften Typ / Name / Wert und initialisieren diese mit den Eigenschaftenwerten vom Knoten?var
.let vs var. Es geht nur um Umfang .
var-Variablen sind global und können grundsätzlich überall aufgerufen werden, während let-Variablen nicht global sind und nur existieren, bis eine schließende Klammer sie beendet.
Sehen Sie sich mein Beispiel unten an und beachten Sie, wie sich die Variable lion (let) in den beiden console.logs unterschiedlich verhält. In der 2. console.log wird der Gültigkeitsbereich überschritten.
quelle
quelle
let ist ein Teil von es6. Diese Funktionen erklären den Unterschied auf einfache Weise.
quelle
Das Folgende zeigt, wie sich 'let' und 'var' im Umfang unterscheiden:
Die
gfoo
, definiert durchlet
zunächst im globalen Bereich , und wenn wir erklären ,gfoo
in der wiederif clause
seinen Umfang geändert und wenn ein neuer Wert auf die Variable in diesem Bereich zugewiesen wird es keinen Einfluss auf die globale Reichweite.Während
hfoo
definiert durchvar
zunächst im globalen Bereich liegt , aber wenn wir es innerhalb des deklarierenif clause
, berücksichtigt es den globalen Bereich hfoo, obwohl var erneut verwendet wurde, um es zu deklarieren. Und wenn wir seinen Wert neu zuweisen, sehen wir, dass auch der globale Bereich hfoo betroffen ist. Dies ist der Hauptunterschied.quelle
Wie oben erwähnt:
Beispiel 1:
In meinen beiden Beispielen habe ich eine Funktion
myfunc
.myfunc
enthält eine Variablemyvar
gleich 10. In meinem ersten Beispiel überprüfe ich, obmyvar
gleich 10 (myvar==10
) ist. Wenn ja, deklariere ich eine Variablemyvar
(jetzt habe ich zwei myvar-Variablen) mit demvar
Schlüsselwort und weise ihr einen neuen Wert zu (20). In der nächsten Zeile drucke ich den Wert auf meiner Konsole. Nach dem bedingten Block drucke ich wieder den Wert vonmyvar
auf meiner Konsole. Wenn Sie sich die Ausgabe von ansehenmyfunc
,myvar
hat der Wert 20.Beispiel 2: In meinem zweiten Beispiel
var
deklariere ich anstelle des Schlüsselworts in meinem bedingten Block diemyvar
Verwendung deslet
Schlüsselworts. Wenn ich jetzt anrufe,myfunc
bekomme ich zwei verschiedene Ausgänge:myvar=20
undmyvar=10
.Der Unterschied ist also sehr einfach, dh sein Umfang.
quelle
Ich möchte diese Schlüsselwörter mit dem Ausführungskontext verknüpfen, da der Ausführungskontext dabei wichtig ist. Der Ausführungskontext besteht aus zwei Phasen: einer Erstellungsphase und einer Ausführungsphase. Darüber hinaus verfügt jeder Ausführungskontext über eine variable Umgebung und eine äußere Umgebung (seine lexikalische Umgebung).
Während der Erstellungsphase eines Ausführungskontexts speichern var, let und const ihre Variable weiterhin im Speicher mit einem undefinierten Wert in der Variablenumgebung des angegebenen Ausführungskontexts. Der Unterschied liegt in der Ausführungsphase. Wenn Sie eine mit var definierte Variable referenzieren, bevor ihr ein Wert zugewiesen wird, ist sie nur undefiniert. Es wird keine Ausnahme gemacht.
Sie können jedoch nicht auf die mit let oder const deklarierte Variable verweisen, bis sie deklariert ist. Wenn Sie versuchen, es zu verwenden, bevor es deklariert wird, wird während der Ausführungsphase des Ausführungskontexts eine Ausnahme ausgelöst. Jetzt befindet sich die Variable dank der Erstellungsphase des Ausführungskontexts weiterhin im Speicher, aber die Engine erlaubt Ihnen nicht, sie zu verwenden:
Wenn bei einer mit var definierten Variablen die Engine die Variable in der Variablenumgebung des aktuellen Ausführungskontexts nicht finden kann, geht sie die Bereichskette (die äußere Umgebung) hoch und überprüft die Variablenumgebung der äußeren Umgebung auf die Variable. Wenn es dort nicht gefunden werden kann, wird die Scope-Kette weiter durchsucht. Dies ist bei let und const nicht der Fall.
Das zweite Merkmal von let ist die Einführung des Blockbereichs. Blöcke werden durch geschweifte Klammern definiert. Beispiele sind Funktionsblöcke, wenn Blöcke, für Blöcke usw. Wenn Sie eine Variable mit let innerhalb eines Blocks deklarieren, ist die Variable nur innerhalb des Blocks verfügbar. Tatsächlich wird jedes Mal, wenn der Block ausgeführt wird, z. B. innerhalb einer for-Schleife, eine neue Variable im Speicher erstellt.
ES6 führt auch das Schlüsselwort const zum Deklarieren von Variablen ein. const hat auch einen Blockumfang. Der Unterschied zwischen let und const besteht darin, dass const-Variablen mit einem Initialisierer deklariert werden müssen, da sonst ein Fehler generiert wird.
Und schließlich werden beim Ausführungskontext mit var definierte Variablen an das Objekt 'this' angehängt. Im globalen Ausführungskontext ist dies das Fensterobjekt in Browsern. Dies ist bei let oder const nicht der Fall.
quelle
Ich denke, die Begriffe und die meisten Beispiele sind etwas überwältigend. Das Hauptproblem, das ich persönlich mit dem Unterschied hatte, ist zu verstehen, was ein "Block" ist. Irgendwann wurde mir klar, dass ein Block alle geschweiften Klammern außer der
IF
Anweisung sein würde. Eine öffnende Klammer{
einer Funktion oder Schleife definiert einen neuen Block. Alles, was darin definiertlet
ist, ist nach der schließenden Klammer}
derselben Sache (Funktion oder Schleife) nicht verfügbar . In diesem Sinne war es einfacher zu verstehen:quelle
Jetzt denke ich, dass es ein besseres Scoping von Variablen für einen Anweisungsblock gibt, indem
let
:Ich denke, die Leute werden let hier später verwenden, damit sie einen ähnlichen Umfang in JavaScript haben wie andere Sprachen, Java, C # usw.
Menschen, die kein klares Verständnis für das Scoping in JavaScript haben, haben den Fehler früher gemacht.
Das Heben wird mit nicht unterstützt
let
.Mit diesem Ansatz werden in JavaScript vorhandene Fehler entfernt.
Siehe ES6 im Detail: let und const , um es besser zu verstehen.
quelle
Dieser Artikel definiert klar den Unterschied zwischen var, let und const
https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b
quelle