2083 Stimmen

Warum ist es keine gute Idee, "for...in" für die Iteration von Arrays zu verwenden?

Ich wurde darauf hingewiesen, dass ich in JavaScript for...in nicht mit Arrays verwenden soll. Warum?

54 Stimmen

Ich habe die kürzlich gestellte Frage gesehen, bei der jemand das zu Ihnen gesagt hat, aber sie meinten nur für Arrays. Es gilt als schlechte Praxis, durch Arrays zu iterieren, aber nicht unbedingt für die Iteration durch Elemente eines Objekts.

22 Stimmen

Viele Antworten mit "for" -Schleifen wie 'for (var i=0; i

3 Stimmen

@MarkSchultheiss Aber das ist eine Rückwärtsschleife. Gibt es eine andere Version der Vorwärtsschleife, die schneller ist?

10voto

matpop Punkte 1870

Außerdem ist aufgrund der Semantik die Art und Weise, wie for, in Arrays behandelt (d.h. genauso wie jedes andere JavaScript-Objekt), nicht mit anderen beliebten Sprachen übereinstimmt.

// C#
char[] a = new char[] {'A', 'B', 'C'};
foreach (char x in a) System.Console.Write(x); //Ausgabe: "ABC"

// Java
char[] a = {'A', 'B', 'C'};
for (char x : a) System.out.print(x);          //Ausgabe: "ABC"

// PHP
$a = array('A', 'B', 'C');
foreach ($a as $x) echo $x;                    //Ausgabe: "ABC"

// JavaScript
var a = ['A', 'B', 'C'];
for (var x in a) document.write(x);            //Ausgabe: "012"

0 Stimmen

Das Argument hier ist, dass es eine schlechte Sache ist, anders zu sein?

0 Stimmen

@LeeGoddard überhaupt nicht, ich weise nur darauf hin, dass normalerweise man für ... in verwendet, um die "Werte" zu durchlaufen, nicht die "Schlüssel". Das Verhalten von JS ist keine schlechte Sache, es kann nur für viele Entwickler, die aus anderen gängigen Programmiersprachen kommen, gegenintuitiv sein, die den Fehler zunächst nicht verstehen und dann lieber for ... in in diesem Zusammenhang nicht verwenden möchten. Das ist alles, was die Antwort hervorhebt, es summiert sich als ein Nachteil, aber natürlich ist das diskutabel.

0 Stimmen

@matpoop - Lebe den Unterschied! Grüße aus dem ehemaligen kommunistischen Osten.

8voto

Pierz Punkte 5458

Ein wichtiger Aspekt ist, dass for...in nur über Eigenschaften eines Objekts iteriert, deren enumerable Eigenschaftsattribut auf true gesetzt ist. Wenn man also versucht, über ein Objekt mit for...in zu iterieren, können beliebige Eigenschaften verpasst werden, wenn ihr enumerable Eigenschaftsattribut falsch ist. Es ist durchaus möglich, das enumerable Eigenschaftsattribut für normale Array-Objekte zu ändern, so dass bestimmte Elemente nicht aufgezählt werden. Im Allgemeinen gelten die Eigenschaftsattribute jedoch für Funktions-Eigenschaften innerhalb eines Objekts.

Man kann den Wert eines Eigenschafts' enumerable Eigenschaftsattribute überprüfen, indem man:

myobject.propertyIsEnumerable('myproperty')

Oder um alle vier Eigenschaftsattribute zu erhalten:

Object.getOwnPropertyDescriptor(myobject,'myproperty')

Dies ist eine Funktion, die in ECMAScript 5 verfügbar ist - in früheren Versionen war es nicht möglich, den Wert des enumerable Eigenschaftsattributs zu ändern (es war immer auf true gesetzt).

8voto

dc1 Punkte 81

Zusätzlich zu den anderen Problemen ist die "for..in"-Syntax wahrscheinlich langsamer, weil der Index ein String und kein Integer ist.

var a = ["a"]
for (var i in a)
    alert(typeof i)  // 'string'
for (var i = 0; i < a.length; i++)
    alert(typeof i)  // 'number'

0 Stimmen

Wahrscheinlich ist es nicht so wichtig. Array-Elemente sind Eigenschaften eines Array-basierten oder Array-ähnlichen Objekts, und alle Objekteigenschaften haben Zeichenfolgenschlüssel. Es sei denn, Ihr JS-Motor optimiert es irgendwie, selbst wenn Sie eine Nummer verwenden würden, würde sie schließlich in eine Zeichenfolge für die Suche umgewandelt werden.

0 Stimmen

Unabhängig von etwaigen Leistungsproblemen, wenn Sie neu in JavaScript sind, verwenden Sie var i in a und erwarten Sie, dass der Index eine Ganzzahl ist, dann wird etwas wie a[i+offset] = Werte an völlig falschen Stellen setzen. ("1" + 1 == "11").

8voto

Ricardo Punkte 89

Das for/in funktioniert mit zwei Arten von Variablen: Hashtabellen (assoziative Arrays) und Arrays (nicht-assoziativ).

JavaScript wird automatisch bestimmen, auf welche Weise es die Elemente durchläuft. Wenn Sie also wissen, dass Ihr Array wirklich nicht-assoziativ ist, können Sie for (var i=0; i<=arrayLen; i++) verwenden und die Autodetektionsschleife überspringen.

Aber meiner Meinung nach ist es besser, for/in zu verwenden, der Prozess, der für diese Autodetektion erforderlich ist, ist sehr gering.

Die richtige Antwort darauf hängt davon ab, wie die Browser den JavaScript-Code interpretieren. Dies kann je nach Browser variieren.

Ich kann mir keinen anderen Zweck vorstellen, for/in nicht zu verwenden;

//Nicht-assoziativ
var arr = ['a', 'b', 'c'];
for (var i in arr)
   alert(arr[i]);

//Assoziativ
var arr = {
   item1 : 'a',
   item2 : 'b',
   item3 : 'c'
};

for (var i in arr)
   alert(arr[i]);

2 Stimmen

for ... in funktioniert mit Objekten. Es gibt keine automatische Erkennung.

7voto

JAL Punkte 20777

Weil es über Eigenschaften iterieren wird, die Objekten in der Prototypenkette gehören, wenn du nicht aufpasst.

Du kannst for.. in verwenden, aber achte darauf, jede Eigenschaft mit hasOwnProperty zu überprüfen.

2 Stimmen

Nicht genug - es ist völlig in Ordnung, beliebig benannte Eigenschaften zu Array-Instanzen hinzuzufügen, und diese werden true von hasOwnProperty() Überprüfungen testen.

0 Stimmen

Guter Punkt, danke. Ich war noch nie dumm genug, das mit einem Array selbst zu tun, also habe ich das nicht in Betracht gezogen!

1 Stimmen

@Pointy Ich habe das nicht getestet, aber vielleicht kann man dies durch Verwendung eines isNaN-Checks für jeden Eigenschaftsnamen überwinden.

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