Ich wurde darauf hingewiesen, dass ich in JavaScript for...in
nicht mit Arrays verwenden soll. Warum?
Das Argument hier ist, dass es eine schlechte Sache ist, anders zu sein?
Ich wurde darauf hingewiesen, dass ich in JavaScript for...in
nicht mit Arrays verwenden soll. Warum?
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"
@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.
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).
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.
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]);
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.
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.
Guter Punkt, danke. Ich war noch nie dumm genug, das mit einem Array selbst zu tun, also habe ich das nicht in Betracht gezogen!
@Pointy Ich habe das nicht getestet, aber vielleicht kann man dies durch Verwendung eines isNaN
-Checks für jeden Eigenschaftsnamen überwinden.
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.
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?
1 Stimmen
@MattDiPasquale - ja, es ist umgekehrt, jedoch bei einer bekannten Grenze ermöglicht es eine optimale Verarbeitung, insbesondere in älteren Browsern durch Iteration über eine bekannte Menge vs. eine unbekannte Satzlänge durch Festlegung der Grenze zuerst. Es ist die Natur einer interpretierten Sprache.
0 Stimmen
@MarkSchultheiss Guter Kommentar. Man könnte auch die
for
-Schleife schreiben alsfor (var i = hColl.length; i--;) {}
, was ein ähnliches Leistungsprofil wie die umgekehrtewhile
-Schleife haben sollte.5 Stimmen
@Wynand verwenden Sie
var i = hCol1.length; for (i; i; i--) {}
speichern Sie den i-Zähler, da dies einen Unterschied macht und den Test vereinfacht. - Je älter der Browser ist, desto größer ist der Unterschied zwischenfor
undwhile
IMMER den "i" Zähler zwischenspeichern - und natürlich passt negativ nicht immer zur Situation, und das negativeverdeckt
den Code etwas für einige Leute. und beachten Sievar i = 1000; for (i; i; i--) {}
undvar b = 1000 for (b; b--;) {}
wobei i von 1000 bis 1 und b von 999 bis 0 geht. - Je älter der Browser ist, desto mehr tendiert der while dazu, die Leistung zu favorisieren.12 Stimmen
Du kannst auch schlau sein.
for(var i = 0, l = myArray.length; i < l; ++i) ...
ist die schnellste und beste Möglichkeit, um eine Vorwärtsiteration durchzuführen.0 Stimmen
Es ist jetzt 10 Jahre später und ich verspüre den Drang hinzuzufügen: Auch wenn diese Optimierungen den Code leicht schneller machen: Es handelt sich um Mikro-Optimierungen. Wenn Sie Zweifel haben, entscheiden Sie sich für lesbaren Code, nicht für eine hoch optimierte Schleife über ein Array mit 1000 Elementen. Wenn etwas langsam ist, dann ist es normalerweise der Code, der innerhalb der Schleife ausgeführt wird, nicht die Schleifensteuerstruktur.