2017-06-17 5 views
8

Ich kenne den Unterschied zwischen Let und Var. let blockiert den Gültigkeitsbereich und var ist der Funktionsumfang.Unterschied zwischen let und var inside setTimeout?

for(var i=0; i< 3; i++){ 
    setTimeout(function(){ 
     console.log(i); 
    }, 10); 
} 

output : 3 
     3 
     3 

Ich weiß, wie Schnipsel über Code funktioniert (console.log(i) zu diesem Zeitpunkt ausgeführt wird, wenn der Wert von i 3 ist, weil Umfang von i global ist).

Aber

for(let i=0; i< 3; i++){ 
    setTimeout(function(){ 
     console.log(i); 
    }, 10); 
} 

output : 1 
     2 
     3 

das Snippet oben Code verwirrend mich. nach mir sollte es Reference Error werfen (weil die Zeit, wenn console.log(i) ausgeführt wird, wird der Wert von i im globalen Bereich nicht im lokalen Bereich aussehen, und ich bin nicht deklarieren/definiert in globalen. so sollte es Referenzfehler geben.)

Wer kann erklären, wie 2nd for loop auf Runtime funktioniert?

+2

Abschluss schließt die neue Instanz von i für jede Iteration bei Verwendung von Let. – Blindman67

+0

Wenn ein 'Reference Error' ausgelöst würde, würde keine Art von Closure funktionieren. Weder die für den Funktionsumfang 'var', noch die für den' let'. –

+0

Gehen Sie und lesen Sie diese [Artikel] (http://www.acreatelygood.com/JavaScript-Scoping-and-Hoisting.html), wenn Sie Zeit haben. Es erklärt Scoping, Hissen usw. sehr gut. – Fahmi

Antwort

2

Wenn Sie in diesem Kontext let verwenden, wird bei jeder Iteration eine neue Bindung/ein neuer Bereich erstellt. Wenn Sie ein ähnliches Verhalten in ES5 mit var erreichen wollen, müssen Sie eine IIFE verwenden:

for (var i = 0; i < 3; i++) { 
 
    (function (i) { 
 
    setTimeout(function() { 
 
     console.log(i); 
 
    }, 10); 
 
    })(i); 
 
}

3

Das zweite Beispiel (unter Verwendung von let) funktioniert, weil eine Funktion löscht alle Variablen schließen darüber sind in Umfang, wenn es erklärt wird. Bei jeder Wiederholung der for-Schleife wird eine neue Variable mit let erzeugt, die Funktion im Timeout schließt sich über der Variablen und behält eine Referenz. Wenn die Funktion nach der Zeitüberschreitung dereferenziert wird, sind es auch ihre Abschlussvariablen.

Weitere Informationen zum Schließen der Funktion finden Sie unter How do JavaScript closures work.

3

Dies ist die Magie der Schließung. In der Seite der Schleife

for(let i=0; i< 3; i++){ 
    setTimeout(function(){ 
     console.log(i); 
    }, 10); 
} 

Sie eine Funktion

function(){ 
    console.log(i); 
} 

Zusätzlich erklärt, die Schleife selbst erklärt ein block

for(let i=0; i< 3; i++){ 
    // this is a block scope because it is contained in 
    // braces 
} 

Variablen definiert mit let sind Block scoped.

Wegen closure, die Funktion, die Sie innerhalb der Schleife deklarieren hat Zugriff auf alle Variablen in ihrem Umfang erklärt und seine Eltern Tive, bis es Müll gesammelt wird.

Ein Abschluss ist die Kombination einer Funktion und der lexikalischen Umgebung , in der diese Funktion deklariert wurde. Diese Umgebung besteht aus lokalen Variablen, die zum Zeitpunkt der Erstellung des Abschlusses in Geltung waren.

Die Variable i ist in-scope wenn die von setTimeout verwendeten Funktionen erstellt werden. Die angegebene i ist eine andere Instanz von i für jede Iteration der Schleife.

Die Funktion existiert bis zu dem von Ihnen angegebenen Intervall. Das ist der Grund, warum jede der 3 Funktionen, die in Ihrer Schleife deklariert sind, den Wert i ausgibt; wurde im enthaltenden Geltungsbereich deklariert und bleibt für die Funktion verfügbar.

Verwandte Themen