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}

551voto

AnthonyWJones Punkte 182582

Die Wahl sollte darauf basieren, welches Idiom am besten verstanden wird.

Ein Array wird iteriert mittels:

for (var i = 0; i < a.length; i++)
   //mache Sachen mit a[i]

Ein Objekt, das als assoziatives Array verwendet wird, wird mittels iteriert:

for (var key in o)
  //mache Sachen mit o[key]

Es sei denn, es gibt erdbebenerregende Gründe, halte dich an das etablierte Nutzungsmuster.

39 Stimmen

Es sollte erwähnt werden, dass es eine gute Praxis ist, for...in mit einer Filterung if-Anweisung zu verwenden. Es gibt eine nützliche Methode des Objekts "obj.hasOwnProperty(member)", die überprüft, ob ein vom Iterator zurückgegebener Member tatsächlich ein Member des Objekts ist. Siehe: javascript.crockford.com/code.html

58 Stimmen

Wie in einem anderen Antwort(en) kommentiert wurde, funktioniert "for...in" nicht korrekt für Arrays, da es über alle Array-Eigenschaften und -Methoden iterieren wird. Verwenden Sie "for...in" daher nur zum Iterieren über Objekteigenschaften. Andernfalls bleiben Sie bei "for(i=0; i

0 Stimmen

Aus Leistungsgründen ist es meiner Meinung nach besser, die Länge des Arrays vor der for-Schleife zu evaluieren, anstatt bei jedem Durchlauf die Länge von a zu evaluieren.

162voto

Benno Richters Punkte 14998

Douglas Crockford empfiehlt in JavaScript: The Good Parts (Seite 24), die Verwendung der Anweisung for in zu vermeiden.

Wenn Sie for in verwenden, um über Eigenschaftsnamen in einem Objekt zu iterieren, sind die Ergebnisse nicht geordnet. Noch schlimmer: Sie könnten unerwartete Ergebnisse erhalten; es beinhaltet Elemente, die von der Prototypenkette geerbt wurden, und den Namen von Methoden.

Alles außer den Eigenschaften kann mit .hasOwnProperty herausgefiltert werden. Dieses Codebeispiel tut, was Sie wahrscheinlich ursprünglich wollten:

for (var name in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, name)) {
        // DO STUFF
    }
}

0 Stimmen

Das zweite - foreach... macht nicht das, was man erwarten könnte (insbesondere wenn man aus .net kommt), und es ist wahrscheinlich nicht das, was du versuchst zu tun.

71 Stimmen

For...in ist perfekt geeignet, um über Objekteigenschaften zu iterieren. Es ist nicht geeignet, um über Array-Elemente zu iterieren. Wenn du den Unterschied zwischen diesen Szenarien nicht verstehen kannst, dann solltest du for...in vermeiden; ansonsten, viel Spaß.

8 Stimmen

Möchten betonen, dass es NICHT BESTELLT ist! Dies könnte ein großes Problem darstellen und wäre ein schwerer Fehler zu finden.

62voto

Jason Punkte 2581

FYI - jQuery-Benutzer


Die each(callback)-Methode von jQuery verwendet standardmäßig eine for( ; ; )-Schleife und wird for( in ) nur verwenden, wenn die Länge undefined ist.

Es ist also sicher anzunehmen, dass die richtige Reihenfolge bei der Verwendung dieser Funktion eingehalten wird.

Beispiel:

$(['a','b','c']).each(function() {
    alert(this);
});
//Gibt "a" dann "b" dann "c" aus

Der Nachteil bei der Verwendung davon ist, dass wenn Sie nicht mit UI-Logik arbeiten, Ihre Funktionen weniger portabel für andere Frameworks sind. Die each()-Funktion ist wahrscheinlich am besten für die Verwendung mit jQuery-Selektoren geeignet und for( ; ; ) wäre anderweitig ratsam.


5 Stimmen

Es gibt immer documentcloud.github.com/underscore, das _.each und viele andere nützliche Funktionen hat

1 Stimmen

Bedeutet dies auch, dass $.each fehlschlägt, wenn ich length-Eigenschaft in meinem Objekt habe? z.B. x = { a:"1", b:"2", length:3 }.

29voto

Gene Punkte 1507

Es gibt Leistungsunterschiede, abhängig davon, welche Art von Schleife Sie verwenden und auf welchem Browser.

Zum Beispiel:

for (var i = myArray.length-1; i >= 0; i--)

ist auf einigen Browsern fast doppelt so schnell wie:

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

Allerdings sind alle schnell genug, es sei denn, Ihre Arrays sind RIESIG oder Sie durchlaufen sie ständig. Ich bezweifle ernsthaft, dass das Schleifen durch Arrays eine Engstelle in Ihrem Projekt ist (oder in einem anderen Projekt, um ehrlich zu sein)

5 Stimmen

Würde das Speichern von "myArray.length" in eine Variable vor der Schleife den Leistungsunterschied beseitigen? Meine Vermutung ist "ja".

0 Stimmen

Es würde zumindest den größten Teil davon beseitigen. Wenn ich mich richtig erinnere, ist i-- jedoch minimal schneller als i++. In jedem Fall sind die Unterschiede sehr gering.

0 Stimmen

Aber wir sprechen hier immer noch über JavaScript, nicht über Assembler, oder? :-)

26voto

Sam Dutton Punkte 13932

Beachten Sie, dass die nativen Array.forEach Methode jetzt weit verbreitet unterstützt wird.

2 Stimmen

Was macht es? Hat es die in anderen Beiträgen erwähnten Probleme (Schleifen über Eigenschaften anstelle von Elementen des Arrays)? Außerdem, da IE8 es nicht unterstützt, ist es etwas weit hergeholt zu sagen, dass es weit verbreitet unterstützt wird.

2 Stimmen

So sehr *nix-Benutzer es verachten, ist IE8 vor allem für Unterfenster7-Benutzer. Das ist ein riesiger Teil des Browsermarktes.

2 Stimmen

@Rauni - Ich verstehe deinen Standpunkt, aber für Desktop-Geräte liegt der IE-Browseranteil laut en.wikipedia.org/wiki/Usage_share_of_web_browsers#Summary_ta‌​ble bei weniger als 40 %, und laut marketshare.hitslink.com/… und anderen Seiten nutzen zumindest 8 % der Browser IE 9. Mit anderen Worten, Array.forEach wird von rund 70 % der Desktop-Browser unterstützt, also halte ich 'weit verbreitet unterstützt' für angemessen. Ich habe nicht nachgeprüft, aber die Mobilunterstützung (auf WebKit- und Opera-Browsern) könnte sogar noch höher sein. Natürlich gibt es erhebliche geografische Unterschiede.

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