2015-04-10 8 views
12

Ich habe Probleme zu verstehen, wie diese for-Schleife in JavaScript endet:Warum beendet "undefined" eine Schleife in JavaScript?

var files = ["A", "B"]; 
for (var i = 0, f; f = files[i]; i++) { 
    console.log(f); 
} 

Sobald er ausgeführt wird, zeigt es A und B auf dem Bildschirm, aber warum Dateien nicht f = [2], um die Schleife zu beenden? Wenn ich f=files[2] in meiner Konsole laufen lasse, bekomme ich die Antwort "undefined", also was ist der Grund dafür, dass dies die Schleife beenden sollte?

Bonusfrage: Warum nicht die Schleife stattdessen wie folgt schreiben?

for (var i=0; i < files.length; i++) { 
    f = files[i]; 
    console.log(f); 
} 

Dies scheint klarer und wartbar zu mir, so ist es aus irgendeinem Grund, dass der erste Teil des Codes über den zweiten verwendet werden würde?

+1

Bonus Antwort: Weil das erste Snippet die ganze Codezeile speichert – Igor

+10

Ich bevorzuge die zweite für die Konsistenz in einem Fall, wo das Array einige gültige Falsy-Wert als 'false',' undefined', 'null' oder' 0 haben könnte '. – Prusse

+0

@Igor Dateien [i] könnte leicht in der zweiten Zeile statt f enthalten sein, so dass die zusätzliche Zeile nicht benötigt wird. das ist genau die Art und Weise, wie die Op es schrieb – rdans

Antwort

22

Die Schleife endet, weil undefined a falsey value.

Der Grund dafür ist bevorzugt Benutzer übereinander verwenden. Sie haben eine Vorliebe, während jemand anders den anderen Weg bevorzugt. Eine andere Person möchte möglicherweise eine While-Schleife verwenden. Es gibt keinen richtigen Weg.

+0

Mit falsch meinst du nicht falsch == undefiniert? machst du ? – cafebabe1991

+1

@ cafebabe1991 'Boolean (undefiniert) === false'. Der Zwang in '==' passt nicht dazu und behandelt 'undefined' als nur sich selbst oder' null'. –

+0

Danke für die Antwort und insbesondere die Verbindung zu den falschen Werten. Das hat viel geklärt und mir geholfen zu verstehen! – Phil

2

Arrays sind beginnend bei Null nummeriert, also Array [] = [0,1,2]. Ihr Code versucht, einen Wert für Dateien [2] zu initialisieren. Dies ist der dritte Platz im Array, aber Ihr Array ist nur mit 2 Leerzeichen definiert. Sobald es sieht, dass es das Ende des Arrays erreicht hat, verlässt es die Schleife.

Wenn einer der Schleifen gegenüber den anderen bevorzugt wird, würde ich annehmen, dass Ihre zweite Schleife besser wäre, weil die erste im Grunde versucht, einen Wert außerhalb der Grenzen im Array zuzuweisen und auszufallen. Ich würde sagen, dass der zweite sicherer ist.

2

Sie haben "undefiniert" nur, wenn Sie den Code in der Konsole ausführen. Denn wenn Sie irgendeinen Code in der Konsole ausführen, wird "undefined" zurückgegeben, wenn keine Dinge zurückgegeben werden.

1

für (ExpressionNoIn opt; Expression opt; Expression opt) Statement

Die erste Expression in der for Anweisung, falls vorhanden, für falsch-ishness geprüft um die Schleife zu verlassen. undefined ist ein Falsy, so dass dies die Schleife beendet.

Wie für die Bonusfrage gibt es viele Möglichkeiten, diese Schleife zu schreiben. Der von Ihnen vorgeschlagene Code ist für mich besser lesbar. Nachdem dies gesagt wurde, können Sie Array.forEach verwenden, um Arrays in neueren Browsern zu iterieren.

1

Bevorzugen for (var i=0; i < files.length; i++) {}

Betrachten arr = [0,1,2]

for (var i = 0; i < arr.length; i++) {} würde korrekt Schleife über alle Elemente in dem Array, aber for (var i = 0, item; item = arr[i]; i++) {} nicht (und wäre vollständig auszuführen fail).

Beachten Sie, dass kein Konstrukt für die Behandlung von Arrays mit geringer Dichte geeignet ist (aber Sie sollten es wahrscheinlich auch als Objekt an diesem Punkt verwenden und behandeln).

Verwenden Sie Array.prototype.forEach oder for(var item in arr) {}, wenn Sie mit Sparse-Arrays arbeiten müssen. Beachten Sie, dass for(var item in arr) {} auch Array.prototype Werte zurückgibt, und dass Array.prototype.forEachnot implemented in every browser ist.

+0

@SalmanA Ich habe meinen Kommentar entfernt. Aber gibt eine der Möglichkeiten, ein Array zu durchlaufen, auch "Länge" zurück? – Toothbrush

+1

@toothbrush Ja, für (var article in arr) läuft das Risiko, über Prototyp-Variablen zu iterieren. Versuchen Sie 'a = [1]; a [10] = 2; Array.prototype.foo =" foo "; für (var i in a) {console.log (i)}' – 00500005

+1

@toothbrush haben einige Browser das und das getan war falsch. Diskutiert im Detail hier: http://StackOverflow.com/q/500504/87015 –