473 Stimmen

JavaScript for...in vs for

Denkst du, dass es einen großen Unterschied zwischen for...in und for-Schleifen gibt? Welche Art von "for" ziehst du vor und warum?

Angenommen, wir haben ein Array von assoziativen Arrays:

var myArray = [{'key': 'value'}, {'key': 'value1'}];

Also können wir durchlaufen:

for (var i = 0; i < myArray.length; i++)

Und:

for (var i in myArray)

Ich sehe keinen großen Unterschied. Gibt es Leistungsprobleme?

13 Stimmen

Beachten Sie, dass wir auch ab JS 1.6 haben: myArray.forEach(callback[, thisarg]).

14 Stimmen

@ Benji array.forEach ist tatsächlich in ES5.

2 Stimmen

In einer for-in Schleife benötigen Sie eine bedingung, die so aussieht: if(myArray.hasOwnProperty(i)){true}

24voto

mikemaccana Punkte 93077

Aktualisierte Antwort für 2012 die aktuelle Version aller gängigen Browser - Chrome, Firefox, IE9, Safari und Opera unterstützen nativen array.forEach von ES5.

Es sei denn, Sie haben einen Grund, IE8 nativ zu unterstützen (bedenken Sie, dass ES5-shim oder Chrome Frame für diese Benutzer bereitgestellt werden können, was eine ordentliche JS-Umgebung bietet), ist es sauberer, einfach die richtige Syntax der Sprache zu verwenden:

myArray.forEach(function(item, index) {
    console.log(item, index);
});

Die vollständige Dokumentation für array.forEach() finden Sie auf MDN.

1 Stimmen

Du solltest wirklich die Parameter des Callbacks dokumentieren: 1. der Elementwert, 2. der Elementindex, 3. das durchlaufene Array

0 Stimmen

Ich verstehe, was du sagst, aber in diesem Fall verschleiert eine zu einfache Darstellung die gesamte Bandbreite der Möglichkeiten. Das Vorhandensein sowohl des Index als auch des Wertes bedeutet, dass es als Ersatz für sowohl for...in als auch forEach...in dienen kann – mit dem Bonus, dass man sich nicht merken muss, welche über Schlüssel oder Werte iteriert.

0 Stimmen

Es gibt viele Leute in Unternehmensumgebungen, die immer noch bei IE 6, 7 und 8 feststecken. Ich würde auf jeden Fall darauf achten, dass Ihre Implementierung für Ihr Publikum geeignet ist.

14voto

Damir Zekić Punkte 15070

Ich stimme den Meinungen zu, dass du die Iterationsmethode entsprechend deiner Bedürfnisse wählen solltest. Ich würde dir tatsächlich empfehlen, niemals durch native Array mit der for in Struktur zu loopen. Es ist deutlich langsamer und, wie Chase Seibert gerade erwähnte, nicht kompatibel mit dem Prototype-Framework.

Es gibt einen ausgezeichneten Vergleich der verschiedenen Schleifenstile, den du dir unbedingt anschauen solltest, wenn du mit JavaScript arbeitest. Führe keine frühen Optimierungen durch, aber behalte diese Informationen irgendwo in deinem Kopf.

Ich würde for in verwenden, um alle Eigenschaften eines Objekts zu bekommen, was besonders hilfreich ist, wenn du deine Skripte debuggst. Zum Beispiel habe ich diese Zeile gerne zur Hand, wenn ich ein unbekanntes Objekt erkunde:

l = ''; for (m in obj) { l += m + ' => ' + obj[m] + '\n' } console.log(l);

Es gibt den Inhalt des gesamten Objekts (zusammen mit Methodenkörpern) in meinem Firebug-Protokoll aus. Sehr praktisch.

0 Stimmen

Der Link ist jetzt defekt. Ich würde gerne den Benchmark sehen, falls jemand einen anderen Link hat.

0 Stimmen

Foreach-Schleifen brechen in Prototyp ab? Da dies jetzt üblicherweise unterstützt wird, ist das etwas, das der Prototyp lösen sollte.

0 Stimmen

Der Link in der Antwort ist veraltet - "404 | Nicht gefunden | Der Inhalt, den Sie suchen, ist nicht mehr auf dieser Seite vorhanden".

14voto

Mike Samuel Punkte 113550

Die beiden sind nicht gleich, wenn das Array lückenhaft ist.

var array = [0, 1, 2, , , 5];

for (var k in array) {
  // Nicht garantiert durch die Sprachspezifikation, um in Reihenfolge zu durchlaufen.
  alert(k);  // Gibt 0, 1, 2, 5 aus.
  // Das Verhalten, wenn der Schleifenkörper zum Array hinzufügt, ist unklar.
}

for (var i = 0; i < array.length; ++i) {
  // Durchläuft in Reihenfolge.
  // i ist eine Zahl, keine Zeichenkette.
  alert(i);  // Gibt 0, 1, 2, 3, 4, 5 aus.
  // Das Verhalten, wenn der Schleifenkörper das Array ändert, ist klarer.
}

14voto

meloncholy Punkte 2022

Mit forEach, um die Prototypenkette zu überspringen

Nur ein schneller Nachtrag zu @nailers Antwort oben, die Verwendung von forEach mit Object.keys bedeutet, dass Sie die Iteration über die Prototypenkette vermeiden können, ohne hasOwnProperty verwenden zu müssen.

var Base = function () {
    this.coming = "hey";
};

var Sub = function () {
    this.leaving = "bye";
};

Sub.prototype = new Base();
var tst = new Sub();

for (var i in tst) {
    console.log(tst.hasOwnProperty(i) + i + tst[i]);
}

Object.keys(tst).forEach(function (val) {
    console.log(val + tst[val]);
});

2 Stimmen

Verdammt, das ist hinterhältig. Es hat sich gelohnt, 50 andere Beiträge zu lesen, um hierher zu kommen. obj={"pink":"Enten", red: "Gänse"}; Object.keys(obj) === ["pink", "red"]

7voto

Matt Lacey Punkte 64983

Ich würde die verschiedenen Methoden je nachdem verwenden, wie ich auf die Elemente verweisen möchte.

Verwende foreach, wenn du nur das aktuelle Element möchtest.

Verwende for, wenn du einen Index benötigst, um relative Vergleiche durchzuführen. (z. B. wie verhält sich dies im Vergleich zum vorherigen/nächsten Element?)

Ich habe noch nie einen Leistungsunterschied bemerkt. Ich würde warten, bis es ein Leistungsproblem gibt, bevor ich mich darum sorge.

0 Stimmen

Schauen Sie unten die Antwort von Bno an - denn ...in macht hier nicht das, was Sie erwarten, und wenn Sie es verwenden, können Sie allerlei Spaß haben. Zur Erinnerung, Prototype macht die Dinge auf die richtige Art und Weise.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X