Warum ist die Verwendung von “for … in” für die Array-Iteration eine schlechte Idee?

Lesezeit: 1 Minute

Warum ist die Verwendung von for in fur die Array Iteration
lyricAlsSH

Mir wurde gesagt, ich solle es nicht verwenden for...in mit Arrays in JavaScript. Warum nicht?

  • Ich habe die letzte Frage gesehen, wo jemand das zu Ihnen gesagt hat, aber sie meinten nur Arrays. Es wird als schlechte Vorgehensweise für das Durchlaufen von Arrays angesehen, aber nicht unbedingt für das Durchlaufen von Elementen eines Objekts.

    – mmurch

    23. November 2010 um 21:21 Uhr

  • Viele Antworten mit “for”-Schleifen wie ‘for (var i=0; i

    – Mark Schultheiss

    22. Juni 2011 um 15:06 Uhr

  • @MarkSchultheiss, aber das ist eine umgekehrte Iteration. Gibt es eine andere Version der Vorwärtsiteration, die schneller ist?

    – ma11hew28

    10. Oktober 2012 um 11:28 Uhr

  • @ Wynand verwenden var i = hCol1.length; for (i;i;i--;) {} Zwischenspeichern Sie das i, da es einen Unterschied macht und den Test vereinfacht. – Je älter der Browser, desto größer der Unterschied zwischen for und while Cachen Sie IMMER den “i”-Zähler – und natürlich passt Negativ nicht immer zur Situation, und das Negativ während obfuscate der Code ein bisschen für manche Leute. und beachten var i = 1000; for (i; i; i--) {} und var b =1000 for (b; b--;) {} wobei i 1000 zu 1 geht und b 999 zu 0 geht. – je älter der Browser, desto mehr tendiert while dazu, die Leistung zu bevorzugen.

    – Mark Schultheiss

    14. März 2013 um 13:07 Uhr


  • Du kannst auch schlau sein. for(var i = 0, l = myArray.length; i < l; ++i) ... ist die schnellste und beste, die Sie mit Vorwärts-Iteration erhalten können.

    – Mathieu Amiot

    17. Juli 2013 um 17:02 Uhr


Warum ist die Verwendung von for in fur die Array Iteration
Kenan-Banken

Der Grund ist, dass ein Konstrukt:

var a = []; // Create a new empty array.
a[5] = 5;   // Perfectly legal JavaScript that resizes the array.

for (var i = 0; i < a.length; i++) {
    // Iterate over numeric indexes from 0 to 5, as everyone expects.
    console.log(a[i]);
}

/* Will display:
   undefined
   undefined
   undefined
   undefined
   undefined
   5
*/

kann manchmal ganz anders sein als die anderen:

var a = [];
a[5] = 5;
for (var x in a) {
    // Shows only the explicitly set index of "5", and ignores 0-4
    console.log(x);
}

/* Will display:
   5
*/

Bedenken Sie das auch JavaScript Bibliotheken können Dinge wie diese tun, die sich auf jedes von Ihnen erstellte Array auswirken:

// Somewhere deep in your JavaScript library...
Array.prototype.foo = 1;

// Now you have no idea what the below code will do.
var a = [1, 2, 3, 4, 5];
for (var x in a){
    // Now foo is a part of EVERY array and 
    // will show up here as a value of 'x'.
    console.log(x);
}

/* Will display:
   0
   1
   2
   3
   4
   foo
*/

  • Denken Sie daran, zu verwenden (var x in a) eher, als (x in a) – möchte keine globale erstellen.

    – Chris Morgan

    25. November 2010 um 2:24 Uhr


  • Das erste Problem ist kein Grund, warum es schlecht ist, nur ein Unterschied in der Semantik. Das zweite Problem scheint mir ein Grund zu sein (zusätzlich zu Konflikten zwischen Bibliotheken, die dasselbe tun), dass das Ändern des Prototyps eines eingebauten Datentyps schlecht ist, anstatt dass for..in schlecht ist.

    – Steward

    1. März 2011 um 0:52 Uhr


  • @Stewart: Alle Objekte in JS sind assoziativ. Ein JS-Array ist ein Objekt, also ja, es ist auch assoziativ, aber dafür ist es nicht gedacht. Wenn Sie über ein Objekt iterieren möchten Schlüsselverwenden for (var key in object). Wenn Sie über ein Array iterieren möchten Elementejedoch verwenden for(var i = 0; i < array.length; i += 1).

    – Martijn

    1. März 2011 um 15:15 Uhr

  • Sie sagten für das erste Beispiel, dass es Iteriert über numerische Indizes von 0 bis 4, wie jeder erwartetICH Erwarten Sie, dass es von 0 bis 5 iteriert! Denn wenn Sie ein Element an Position 5 hinzufügen, hat das Array 6 Elemente (5 davon undefiniert).

    – stivlo

    22. Oktober 2011 um 10:53 Uhr


  • Ich denke, die Beispiele würden noch deutlicher, wenn Sie a festlegen[5] auf etwas anderes als 5, sagen wir, a[5]=42. Die Tatsache, dass das zweite Beispiel (“für (x in a)” nur einen Wert aufzählt, überrascht mich nicht; die Tatsache, dass der Wert, den es aufzählt, 5 statt 42 ist, überrascht mich (kommt aus anderen Sprachen mit einem ähnlichen Konstrukt die Listeninhalte anstelle von Array-Indizes aufzählt).

    – metamatt

    3. Dezember 2012 um 23:56 Uhr


1646894718 750 Warum ist die Verwendung von for in fur die Array Iteration
Christian C. Salvado

Die for-in Aussage an sich ist keine “schlechte Praxis”, wie auch immer sie sein kann missbrauchtzum Beispiel zu iterieren über Arrays oder Array-ähnliche Objekte.

Der Zweck der for-in Aussage ist zu aufzählen über Objekteigenschaften. Diese Anweisung wird in der Prototyp-Kette auftauchen und auch überzählen vererbt Eigenschaften, eine Sache, die manchmal ist nicht erwünscht.

Außerdem ist die Reihenfolge der Iteration nicht durch die Spezifikation garantiert, dh wenn Sie ein Array-Objekt “iterieren” möchten, können Sie mit dieser Anweisung nicht sicher sein, dass die Eigenschaften (Array-Indizes) in der numerischen Reihenfolge besucht werden.

Beispielsweise wird in JScript (IE <= 8) die Reihenfolge der Aufzählung sogar für Array-Objekte definiert, wenn die Eigenschaften erstellt wurden:

var array = [];
array[2] = 'c';
array[1] = 'b';
array[0] = 'a';

for (var p in array) {
  //... p will be "2", "1" and "0" on IE
}

Apropos vererbte Eigenschaften, wenn Sie z. B. die erweitern Array.prototype Objekt (wie einige Bibliotheken wie MooTools), werden diese Eigenschaften ebenfalls aufgelistet:

Array.prototype.last = function () { return this[this.length-1]; };

for (var p in []) { // an empty array
  // last will be enumerated
}

Wie ich schon sagte zu iterieren gegenüber Arrays oder Array-ähnlichen Objekten verwenden Sie am besten a sequentielle Schleifewie z. B. eine einfache alte for/while Schleife.

Wenn Sie nur die aufzählen möchten eigene Eigenschaften eines Objekts (diejenigen, die nicht geerbt werden), können Sie die verwenden hasOwnProperty Methode:

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    // prop is not inherited
  }
}

Und einige Leute empfehlen sogar, die Methode direkt von aufzurufen Object.prototype um Probleme zu vermeiden, wenn jemand eine Eigenschaft namens hinzufügt hasOwnProperty zu unserem Objekt:

for (var prop in obj) {
  if (Object.prototype.hasOwnProperty.call(obj, prop)) {
    // prop is not inherited
  }
}

  • Siehe auch den Beitrag von David Humphrey Schnelles Iterieren über Objekte in JavaScript – für Arrays for..in ist viel langsamer als “normale” Schleifen.

    – Chris Morgan

    25. November 2010 um 2:25 Uhr

  • Frage zum letzten Punkt zu “hasOwnProperty”: Wenn jemand “hasOwnProperty” an einem Objekt überschreibt, gibt es Probleme. Aber werden Sie nicht die gleichen Probleme haben, wenn jemand “Object.prototype.hasOwnProperty” überschreibt? Wie auch immer, sie vermasseln dich und es liegt nicht in deiner Verantwortung, oder?

    – Scott Rippey

    14. Januar 2011 um 0:08 Uhr

  • Du sagst for..in ist keine schlechte Praxis, aber es kann missbraucht werden. Haben Sie ein praktisches Beispiel aus der Praxis, bei dem Sie wirklich alle Eigenschaften eines Objekts, einschließlich geerbter Eigenschaften, durchgehen wollten?

    – rjmunro

    3. Juli 2013 um 12:05 Uhr

  • @ScottRippey: Wenn du es dorthin bringen willst: youtube.com/watch?v=FrFUI591WhI

    – Nathan Wand

    29. Mai 2014 um 15:24 Uhr

  • Mit dieser Antwort habe ich festgestellt, dass man mit auf den Wert zugreifen kann for (var p in array) { array[p]; }

    – Äquimann

    20. April 2017 um 13:08 Uhr


1646894718 20 Warum ist die Verwendung von for in fur die Array Iteration
Christoph

Es gibt drei Gründe, warum Sie es nicht verwenden sollten for..in um über Array-Elemente zu iterieren:

  • for..in wird alle eigenen und geerbten Eigenschaften des Array-Objekts durchlaufen, die es nicht sind DontEnum; das heißt, wenn jemand dem bestimmten Array-Objekt Eigenschaften hinzufügt (dafür gibt es triftige Gründe – ich habe dies selbst getan) oder geändert Array.prototype (was in Code, der gut mit anderen Skripten funktionieren soll, als schlechte Praxis angesehen wird), werden diese Eigenschaften ebenfalls durchlaufen; vererbte Eigenschaften können durch Ankreuzen ausgeschlossen werden hasOwnProperty()aber das hilft Ihnen nicht mit Eigenschaften, die im Array-Objekt selbst festgelegt sind

  • for..in Es ist nicht garantiert, dass die Elementreihenfolge beibehalten wird

  • Es ist langsam, weil Sie alle Eigenschaften des Array-Objekts und seiner gesamten Prototypkette durchlaufen müssen und immer noch nur den Namen der Eigenschaft erhalten, dh um den Wert zu erhalten, ist eine zusätzliche Suche erforderlich

1646894719 573 Warum ist die Verwendung von for in fur die Array Iteration
Pim Jäger

Weil for…in durch das Objekt aufzählt, das das Array enthält, nicht das Array selbst. Wenn ich der Arrays-Prototypenkette eine Funktion hinzufüge, wird diese ebenfalls eingeschlossen. Dh

Array.prototype.myOwnFunction = function() { alert(this); }
a = new Array();
a[0] = 'foo';
a[1] = 'bar';
for(x in a){
 document.write(x + ' = ' + a[x]);
}

Dies wird schreiben:

0 = foo
1 = bar
myOwnFunction = function() { alert(this); }

Und da Sie nie sicher sein können, dass der Prototypkette nichts hinzugefügt wird, verwenden Sie einfach eine for-Schleife, um das Array aufzuzählen:

for(i=0,x=a.length;i<x;i++){
 document.write(i + ' = ' + a[i]);
}

Dies wird schreiben:

0 = foo
1 = bar

Ab 2016 (ES6) dürfen wir verwenden for…of für die Array-Iteration, wie John Slegers bereits bemerkt hat.

Ich möchte nur diesen einfachen Demonstrationscode hinzufügen, um die Dinge klarer zu machen:

Array.prototype.foo = 1;
var arr = [];
arr[5] = "xyz";

console.log("for...of:");
var count = 0;
for (var item of arr) {
    console.log(count + ":", item);
    count++;
    }

console.log("for...in:");
count = 0;
for (var item in arr) {
    console.log(count + ":", item);
    count++;
    }

Die Konsole zeigt:

for...of:

0: undefined
1: undefined
2: undefined
3: undefined
4: undefined
5: xyz

for...in:

0: 5
1: foo

Mit anderen Worten:

  • for...of zählt von 0 bis 5 und ignoriert auch Array.prototype.foo. Es zeigt Array Werte.

  • for...in listet nur die auf 5wobei undefinierte Array-Indizes ignoriert, aber hinzugefügt werden foo. Es zeigt Array Eigenschaftsnamen.

Kurze Antwort: Es lohnt sich einfach nicht.


Längere Antwort: Es lohnt sich einfach nicht, auch wenn keine sequentielle Elementreihenfolge und optimale Leistung erforderlich sind.


Lange Antwort: Es lohnt sich einfach nicht…

  • Verwenden for (var property in array) wird verursachen array als iteriert werden Objektdurchläuft die Objektprototypkette und ist letztendlich langsamer als ein indexbasiertes for Schleife.
  • for (... in ...) Es ist nicht garantiert, dass die Objekteigenschaften wie erwartet in sequenzieller Reihenfolge zurückgegeben werden.
  • Verwenden hasOwnProperty() und !isNaN() Überprüfungen zum Filtern der Objekteigenschaften sind ein zusätzlicher Overhead, der dazu führt, dass es noch langsamer arbeitet, und macht den Hauptgrund für seine Verwendung überhaupt zunichte, dh wegen des kürzeren Formats.

Aus diesen Gründen gibt es nicht einmal einen akzeptablen Kompromiss zwischen Leistung und Komfort. Es gibt wirklich keinen Vorteil, es sei denn, die Absicht ist, das Array als zu behandeln Objekt und Operationen an den Objekteigenschaften des Arrays ausführen.

1646894719 367 Warum ist die Verwendung von for in fur die Array Iteration
Erich König

Isoliert ist nichts falsch daran, for-in auf Arrays zu verwenden. For-in iteriert über die Eigenschaftsnamen eines Objekts, und im Fall eines „vorkonfigurierten“ Arrays entsprechen die Eigenschaften den Array-Indizes. (Die eingebauten Eigenschaften wie length, toString usw. sind nicht in der Iteration enthalten.)

Wenn Ihr Code (oder das von Ihnen verwendete Framework) jedoch benutzerdefinierte Eigenschaften zu Arrays oder zum Array-Prototyp hinzufügt, werden diese Eigenschaften in die Iteration eingeschlossen, was wahrscheinlich nicht das ist, was Sie möchten.

Einige JS-Frameworks, wie Prototype, modifizieren den Array-Prototyp. Andere Frameworks wie JQuery haben dies nicht, daher können Sie mit JQuery sicher for-in verwenden.

Wenn Sie Zweifel haben, sollten Sie for-in wahrscheinlich nicht verwenden.

Eine alternative Möglichkeit, ein Array zu durchlaufen, ist die Verwendung einer for-Schleife:

for (var ix=0;ix<arr.length;ix++) alert(ix);

Dies hat jedoch ein anderes Problem. Das Problem ist, dass ein JavaScript-Array “Löcher” haben kann. Wenn Sie definieren arr als:

var arr = ["hello"];
arr[100] = "goodbye";

Dann hat das Array zwei Elemente, aber eine Länge von 101. Die Verwendung von for-in ergibt zwei Indizes, während die for-Schleife 101 Indizes ergibt, wobei 99 einen Wert von hat undefined.

986700cookie-checkWarum ist die Verwendung von “for … in” für die Array-Iteration eine schlechte Idee?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy