Durchläuft die Schleife "for ... in" in Javascript die Hashtabellen / Elemente in der Reihenfolge, in der sie deklariert sind? Gibt es einen Browser, der dies nicht in der richtigen Reihenfolge tut?
Das Objekt Ich möchte Verwendung wird deklariert werden einmal und nie geändert werden.
Angenommen, ich habe:
var myObject = { A: "Hello", B: "World" };
Und ich benutze sie weiter in:
for (var item in myObject) alert(item + " : " + myObject[item]);
Kann ich erwarten, dass 'A: "Hallo" in den meisten anständigen Browsern immer vor' B: "Welt" steht?
javascript
for-loop
Chakrit
quelle
quelle
Antworten:
Zitiert John Resig :
Alle Browser respektieren die Definitionsreihenfolge mit Ausnahme von Chrome und Opera, die für jeden nicht numerischen Eigenschaftsnamen gelten. In diesen beiden Browsern werden die Eigenschaften in der Reihenfolge vor der ersten nicht numerischen Eigenschaft abgerufen (dies hängt damit zusammen, wie sie Arrays implementieren). Die Reihenfolge ist auch für die gleiche
Object.keys
.Dieses Beispiel soll deutlich machen, was passiert:
Die technischen Details sind weniger wichtig als die Tatsache, dass sich dies jederzeit ändern kann. Verlassen Sie sich nicht darauf, dass die Dinge so bleiben.
Kurz gesagt: Verwenden Sie ein Array, wenn Ihnen die Reihenfolge wichtig ist.
quelle
Ein Jahr später ...
Es ist 2012 und die wichtigsten Browser unterscheiden sich immer noch :
Kern oder Test im aktuellen Browser
Safari 5, Firefox 14
Chrome 21, Opera 12, Knoten 0.6, Firefox 27
IE9
quelle
delete
ist interessant, da zumindest in V8 das Objekt sofort durch eine Hash-Tabelle gesichert wird. Die Hash-Tabelle in V8 wird jedoch in der Einfügereihenfolge gespeichert. Das interessanteste Ergebnis hier ist IE, ich frage mich, was für eine Hässlichkeit sie tun, um das durchzuziehen ...Aus der ECMAScript-Sprachspezifikation , Abschnitt 12.6.4 (in der
for .. in
Schleife):Und Abschnitt 4.3.3 (Definition von "Objekt"):
Ich denke, das bedeutet, dass Sie sich nicht darauf verlassen können, dass die Eigenschaften in JavaScript-Implementierungen in einer einheitlichen Reihenfolge aufgelistet werden. (Es wäre sowieso ein schlechter Stil, sich auf implementierungsspezifische Details einer Sprache zu verlassen.)
Wenn Sie möchten, dass Ihre Reihenfolge definiert wird, müssen Sie etwas implementieren, das sie definiert, z. B. ein Array von Schlüsseln, die Sie sortieren, bevor Sie damit auf das Objekt zugreifen.
quelle
Die Elemente eines Objekts, die für / in Aufzählungen aufgeführt sind, sind die Eigenschaften, für die das DontEnum-Flag nicht gesetzt ist. Der ECMAScript-Standard, auch bekannt als Javascript, besagt ausdrücklich, dass "Ein Objekt eine ungeordnete Sammlung von Eigenschaften ist" (siehe http://www.mozilla.org/js/language/E262-3.pdf, Abschnitt 8.6).
Es wird nicht standardkonform (dh sicher) sein, anzunehmen, dass alle Javascript-Implementierungen in der Reihenfolge der Deklaration aufgelistet werden.
quelle
Die Iterationsreihenfolge wird auch in Bezug auf das Löschen von Eigenschaften verwechselt, in diesem Fall jedoch nur mit dem IE.
Der Wunsch, die Spezifikation zu ändern, um die Iterationsreihenfolge zu korrigieren, scheint unter Entwicklern ein recht beliebter Wunsch zu sein, wenn die Diskussion unter http://code.google.com/p/v8/issues/detail?id=164 ein Hinweis ist.
quelle
In IE6 ist die Reihenfolge nicht garantiert.
quelle
Der Bestellung kann nicht vertraut werden. Sowohl Opera als auch Chrome geben die Liste der ungeordneten Eigenschaften zurück.
Der obige Code zeigt B, A, C in Opera und C, A, B in Chrome.
quelle
Dies beantwortet die Frage an sich nicht, bietet aber eine Lösung für das Grundproblem.
Angenommen, Sie können sich nicht auf die Reihenfolge verlassen, um sie zu erhalten, warum nicht ein Array von Objekten mit Schlüssel und Wert als Eigenschaften verwenden?
Jetzt müssen Sie sicherstellen, dass die Schlüssel eindeutig sind (vorausgesetzt, dies ist auch für Sie wichtig. Auch direkte Adressierungsänderungen und für (... in ...) geben jetzt Indizes als 'Schlüssel' zurück.
Siehe den Stift für (... in ...) Adressierung in der Reihenfolge von JDQ ( @JDQ ) auf CodePen .quelle