Denken Sie, dass es einen großen Unterschied zwischen for ... in und for-Schleifen gibt? Welche Art von "für" bevorzugen Sie und warum?
Angenommen, wir haben ein Array von assoziativen Arrays:
var myArray = [{'key': 'value'}, {'key': 'value1'}];
So können wir iterieren:
for (var i = 0; i < myArray.length; i++)
Und:
for (var i in myArray)
Ich sehe keinen großen Unterschied. Gibt es Leistungsprobleme?
javascript
andrii
quelle
quelle
myArray.forEach(callback[, thisarg])
.if(myArray.hasOwnProperty(i)){true}
['foo', 'bar', 'baz'].forEach(function(element, index, array){ console.log(element, index, array); });
ist in Ordnung, so ziemlich überall zu verwenden, außer in IE8- und es ist bei weitem die eleganteste Syntaxfor...of
Aussage in ECMAScript 6 , zum Beispiel:for (let i of myArray) console.log(i);
Antworten:
Die Wahl sollte auf der Sprache basieren, die am besten verstanden wird.
Ein Array wird iteriert mit:
Ein Objekt, das als assoziatives Array verwendet wird, wird iteriert mit:
Halten Sie sich an das etablierte Verwendungsmuster, es sei denn, Sie haben erderschütternde Gründe.
quelle
for
bewerten und nicht jedes Mal in der Schleife eine Länge zu bewerten .i < l
nichti < a
in deinem For-Loop-Zustand.Douglas Crockford empfiehlt in JavaScript: The Good Parts (Seite 24), die Verwendung der
for in
Anweisung zu vermeiden .Wenn Sie die
for in
Eigenschaftsnamen in einem Objekt durchlaufen, werden die Ergebnisse nicht sortiert. Schlimmer noch: Möglicherweise erhalten Sie unerwartete Ergebnisse. Es enthält Mitglieder, die von der Prototypenkette geerbt wurden, und den Namen der Methoden.Alles außer den Eigenschaften kann mit herausgefiltert werden
.hasOwnProperty
. Dieses Codebeispiel macht das, was Sie ursprünglich wahrscheinlich wollten:quelle
name
Variable zu deklarierenfor(var name in object)...
. Andernfalls befindet sich die Variable , wenn sie sich beispielsweise in einer Funktion befindetname
, eine Eigenschaft des globalen Objekts (eine Zuweisung zu einem nicht deklarierten Bezeichner übernimmt dies), auch im neuen ECMAScript 5 Strenger Modus, dieser Code wirft aReferenceError
.Zu Ihrer Information - jQuery-Benutzer
Die
each(callback)
Methodefor( ; ; )
von jQuery verwendet standardmäßig eine Schleife und wirdfor( in )
nur verwendet, wenn die Länge gleich istundefined
.Daher würde ich sagen, dass es sicher ist, bei Verwendung dieser Funktion die richtige Reihenfolge anzunehmen.
Beispiel :
Der Nachteil bei der Verwendung ist, dass Ihre Funktionen für andere Frameworks weniger portabel sind, wenn Sie eine Nicht-UI-Logik verwenden. Die
each()
Funktion ist wahrscheinlich am besten für die Verwendung mit jQuery-Selektoren reserviert undfor( ; ; )
kann ansonsten empfohlen werden.quelle
Es gibt Leistungsunterschiede, je nachdem, welche Art von Schleife Sie verwenden und in welchem Browser.
Zum Beispiel:
ist in einigen Browsern fast doppelt so schnell wie:
Wenn Ihre Arrays jedoch nicht RIESIG sind oder Sie sie ständig schleifen, sind alle schnell genug. Ich bezweifle ernsthaft, dass Array-Looping ein Engpass in Ihrem Projekt ist (oder für jedes andere Projekt in dieser Angelegenheit).
quelle
for(var i = myArray.length; i--;)
Beachten Sie, dass die native Array.forEach-Methode jetzt weitgehend unterstützt wird .
quelle
Die aktualisierte Antwort für die aktuelle Version 2012 aller gängigen Browser - Chrome, Firefox, IE9, Safari und Opera - unterstützt das native Array.forEach von ES5.
Sofern Sie keinen Grund haben, IE8 nativ zu unterstützen (unter Berücksichtigung der Tatsache, dass diesen Benutzern ES5-Shim oder Chrome-Frame zur Verfügung gestellt werden können, um eine ordnungsgemäße JS-Umgebung bereitzustellen), ist es sauberer, einfach die richtige Syntax der Sprache zu verwenden:
Die vollständige Dokumentation für array.forEach () finden Sie unter MDN.
quelle
Die beiden sind nicht gleich, wenn das Array dünn ist.
quelle
Verwenden von forEach zum Überspringen der Prototypenkette
Nur eine kurze Ergänzung zu der Antwort von @ nailer oben : Wenn Sie forEach mit Object.keys verwenden, können Sie vermeiden, dass Sie über die Prototypenkette iterieren, ohne hasOwnProperty verwenden zu müssen.
quelle
Ich bin der Meinung, dass Sie die Iterationsmethode entsprechend Ihren Anforderungen auswählen sollten. Ich würde vorschlagen, dass Sie eigentlich nie native
Array
mitfor in
Struktur durchlaufen . Es ist viel langsamer und , wie Chase Seibert im Moment betonte, nicht mit dem Prototype-Framework kompatibel.Es gibt einen hervorragenden Benchmark für verschiedene Schleifenstile, den Sie unbedingt beachten sollten, wenn Sie mit JavaScript arbeiten . Nehmen Sie keine frühen Optimierungen vor, aber Sie sollten das Zeug irgendwo im Hinterkopf behalten.
Ich würde verwenden
for in
, um alle Eigenschaften eines Objekts abzurufen, was besonders beim Debuggen Ihrer Skripte nützlich ist. Zum Beispiel möchte ich diese Zeile zur Hand haben, wenn ich unbekannte Objekte erkunde:Es speichert den Inhalt des gesamten Objekts (zusammen mit den Methodenkörpern) in meinem Firebug-Protokoll. Sehr praktisch.
quelle
Hier ist etwas, was ich getan habe.
So würden Sie es verwenden.
Dies funktioniert bei Arrays und Objekten (z. B. einer Liste von HTML-Elementen).
Ich habe das gerade gemacht, also bin ich offen für Vorschläge :)
quelle
Ich würde die verschiedenen Methoden verwenden, basierend darauf, wie ich auf die Elemente verweisen wollte.
Verwenden Sie foreach, wenn Sie nur das aktuelle Element möchten.
Verwenden Sie diese Option, wenn Sie einen Indexer für relative Vergleiche benötigen. (Dh wie ist das im Vergleich zum vorherigen / nächsten Artikel?)
Ich habe noch nie einen Leistungsunterschied bemerkt. Ich würde warten, bis ein Leistungsproblem auftritt, bevor ich mir darüber Sorgen mache.
quelle
Mit for (var i in myArray) können Sie auch Objekte durchlaufen , ich werde den Schlüsselnamen enthalten und Sie können über myArray [i] auf die Eigenschaft zugreifen . Zusätzlich werden alle Methoden, die Sie dem Objekt hinzugefügt haben, ebenfalls in die Schleife aufgenommen, dh wenn Sie ein externes Framework wie jQuery oder Prototype verwenden oder wenn Sie Methoden direkt zu Objektprototypen hinzufügen, an einem Punkt, auf den ich verweise diese Methoden.
quelle
Achtung!
Wenn Sie mehrere Skript-Tags haben und beispielsweise Informationen in Tag-Attributen suchen, müssen Sie die Eigenschaft .length mit einer for-Schleife verwenden, da es sich nicht um ein einfaches Array, sondern um ein HTMLCollection-Objekt handelt.
https://developer.mozilla.org/en/DOM/HTMLCollection
Wenn Sie die foreach-Anweisung für (var i in yourList) verwenden, werden in den meisten Browsern Eigenschaften und Methoden der HTMLCollection zurückgegeben!
Selbst wenn getElementsByTagName eine NodeList zurückgeben sollte, geben die meisten Browser eine HTMLCollection zurück: https://developer.mozilla.org/en/DOM/document.getElementsByTagName
quelle
Denn in-Schleifen auf Arrays sind nicht mit Prototype kompatibel. Wenn Sie der Meinung sind, dass Sie diese Bibliothek in Zukunft möglicherweise verwenden müssen, ist es sinnvoll, sich an for-Schleifen zu halten.
http://www.prototypejs.org/api/array
quelle
Ich habe Probleme mit dem "für jeden" bei der Verwendung von Objekten, Prototypen und Arrays gesehen
Mein Verständnis ist, dass das für jedes für Eigenschaften von Objekten und NICHT Arrays ist
quelle
Wenn Sie Ihren Code wirklich beschleunigen möchten, was ist damit?
Es ist eine Art while-Logik in der for-Anweisung und weniger redundant. Firefox hat auch Array.forEach und Array.filter
quelle
Ein kürzerer und bester Code laut jsperf ist
quelle
Verwenden Sie die Array (). ForEach-Schleife, um die Parallelität zu nutzen
quelle
Array.prototype.forEach
nicht mehrere Aufrufe des Rückrufs gleichzeitig ausgeführt werden.für (;;) ist für Arrays : [20,55,33]
for..in ist für Objekte : {x: 20, y: 55: z: 33}
quelle
Achtung!!! Ich verwende Chrome 22.0 unter Mac OS und habe Probleme mit der Syntax für jede Syntax.
Ich weiß nicht, ob dies ein Browserproblem, ein Javascript-Problem oder ein Fehler im Code ist, aber es ist SEHR seltsam. Außerhalb des Objekts funktioniert es perfekt.
quelle
Es gibt einen wichtigen Unterschied zwischen beiden. Das For-In durchläuft die Eigenschaften eines Objekts. Wenn es sich also um ein Array handelt, durchläuft es nicht nur seine Elemente, sondern auch die Funktion "Entfernen".
Sie können das For-In mit einem verwenden
if(myArray.hasOwnProperty(i))
. Wenn ich über Arrays iteriere, ziehe ich es jedoch immer vor, dies zu vermeiden und nur die for (;;) - Anweisung zu verwenden.quelle
Obwohl beide sehr ähnlich sind, gibt es einen kleinen Unterschied:
In diesem Fall lautet die Ausgabe:
STANDARD FÜR LOOP:
ARRAY [0] = A.
ARRAY [1] = B.
ARRAY [2] = C.
In diesem Fall lautet die Ausgabe:
FOR-IN-SCHLEIFE:
ARRAY [1] = B.
ARRAY [2] = C.
ARRAY [10] = D.
ARRAY [ABC] = 123
quelle
Die for in-Anweisung ermöglicht das Durchlaufen der Namen aller Eigenschaften eines Objekts. Leider durchläuft es auch alle Mitglieder, die durch die Prototypenkette geerbt wurden. Dies hat den schlechten Nebeneffekt, dass Methodenfunktionen bereitgestellt werden, wenn das Interesse an den Datenelementen liegt.
quelle