Frage

Ok, also auf einer Webseite, habe ich ein JavaScript-Objekt bekommt, die ich als assoziatives Array bin mit. Dieses besteht statisch in einem Skriptblock, wenn die Seite geladen wird:

var salesWeeks = {
    "200911" : ["11 / 2009", "Fiscal 2009"],
    "200910" : ["10 / 2009", "Fiscal 2009"],
    "200909" : ["09 / 2009", "Fiscal 2009"],
    "200908" : ["08 / 2009", "Fiscal 2009"],
    "200907" : ["07 / 2009", "Fiscal 2009"],
    "200906" : ["06 / 2009", "Fiscal 2009"],
    "200905" : ["05 / 2009", "Fiscal 2009"],
    "200904" : ["04 / 2009", "Fiscal 2009"],
    "200903" : ["03 / 2009", "Fiscal 2009"],
    "200902" : ["02 / 2009", "Fiscal 2009"],
    "200901" : ["01 / 2009", "Fiscal 2009"],
    "200852" : ["52 / 2008", "Fiscal 2009"],
    "200851" : ["51 / 2008", "Fiscal 2009"]
};

Die Reihenfolge der Schlüssel / Wert-Paaren ist gewollt, da ich das Objekt in ein HTML-Auswahlbox wie diese drehen:

<select id="ddl_sw" name="ddl_sw">
<option value="">== SELECT WEEK ==</option>
<option value="200911">11 / 2009 (Fiscal 2009)</option>
<option value="200910">10 / 2009 (Fiscal 2009)</option>
<option value="200909">09 / 2009 (Fiscal 2009)</option>
<option value="200908">08 / 2009 (Fiscal 2009)</option>
<option value="200907">07 / 2009 (Fiscal 2009)</option>
<option value="200906">06 / 2009 (Fiscal 2009)</option>
<option value="200905">05 / 2009 (Fiscal 2009)</option>
<option value="200904">04 / 2009 (Fiscal 2009)</option>
<option value="200903">03 / 2009 (Fiscal 2009)</option>
<option value="200902">02 / 2009 (Fiscal 2009)</option>
<option value="200901">01 / 2009 (Fiscal 2009)</option>
<option value="200852">52 / 2008 (Fiscal 2009)</option>
<option value="200851">51 / 2008 (Fiscal 2009)</option>
</select>

... mit Code, der wie folgt aussieht (aus einer Funktion snipped):

var arr = [];
arr.push(
    "<select id=\"ddl_sw\" name=\"ddl_sw\">" +
    "<option value=\"\">== SELECT WEEK ==</option>"
);

for(var key in salesWeeks)
{
    arr.push(
        "<option value=\"" + key + "\">" +
        salesWeeks[key][0] + " (" + salesWeeks[key][1] + ")" +
        "<\/option>"
    );
}

arr.push("<\/select>");

return arr.join("");

Das alles funktioniert gut in IE, Firefox und Opera.

Doch in Chrome, der Auftrag kommt alles seltsam:

<select id="ddl_sw" name="ddl_sw">
<option value="">== SELECT WEEK ==</option>
<option value="200852">52 / 2008 (Fiscal 2009)</option>
<option value="200908">08 / 2009 (Fiscal 2009)</option>
<option value="200906">06 / 2009 (Fiscal 2009)</option>
<option value="200902">02 / 2009 (Fiscal 2009)</option>
<option value="200907">07 / 2009 (Fiscal 2009)</option>
<option value="200904">04 / 2009 (Fiscal 2009)</option>
<option value="200909">09 / 2009 (Fiscal 2009)</option>
<option value="200903">03 / 2009 (Fiscal 2009)</option>
<option value="200905">05 / 2009 (Fiscal 2009)</option>
<option value="200901">01 / 2009 (Fiscal 2009)</option>
<option value="200910">10 / 2009 (Fiscal 2009)</option>
<option value="200911">11 / 2009 (Fiscal 2009)</option>
<option value="200851">51 / 2008 (Fiscal 2009)</option>
</select>

Hinweis: Die Bestellung, obwohl seltsam, ändert sich nicht auf nachfolgende Aktualisierungen. Es ist immer in dieser Reihenfolge.

Also, was macht Chrome? Einige Optimierung, wie es verarbeitet die Schleife?

In erster Linie bin ich falsch in der Größenordnung zu verlassen, dass die Schlüssel / Wert-Paare in deklariert sind jeder assoziatives Array?

ich nie in Frage gestellt, bevor es nehme ich an, nur die Reihenfolge, weil diese Technik für mich schon immer in den anderen Browsern gearbeitet halten würde. Aber ich nehme an, ich habe es nie irgendwo gesehen angegeben, dass die Reihenfolge garantiert. Vielleicht ist es nicht?

Jeder Einblick wäre genial. Danke.

War es hilfreich?

Lösung

Denken eines assoziativen Array als Papiersack in dem alle Schlüssel-Wert-Paare gesetzt werden. Wie Sie Ihre Hand in den Sack erreichen bei den Paaren suchen (wie mit der für ... in Schleife), dass die Reihenfolge, die Sie begegnen, ist für alle praktischen Zwecke zufällig.

Wenn Sie sie in einer bestimmten Reihenfolge sehen möchten, müssen Sie die Schlüssel in einem Array extrahieren und sortieren. Dann gehen Sie über das Array mit den Tasten Sie indizieren in das assoziative Array auftreten.

Andere Tipps

Die Reihenfolge, in der Elemente in einem assoziativen Array gespeichert sind, ist nicht garantiert. Sie werden ausdrücklich die Ausgabe sortiert werden müssen.

Wie die anderen Antworten sagen, die Reihenfolge, in der die Eigenschaften eines Objekts durchlaufen werden, ist in der Spezifikation nicht definiert, obwohl die gängigen Browser alle sie in der definierten Reihenfolge durchlaufen.

Chrome wird sie in der Reihenfolge aufzählen zu, wenn alle die Eigenschaften des Objekts primitive Werte enthalten. John Resig gibt weitere Einzelheiten über Chrome Verhalten hier (unter „for-Schleife order“): http://ejohn.org/blog/javascript-in-chrome/

Wie bereits ausgeführt Chrome Verhalten ist vollkommen gültig.

Dies ist ein guter Fall, wo einige OO denken helfen kann. Haben Sie wirklich ein assoziatives Array wollen oder einfach nur eine Liste von Objekten?

var salesWeeks = [
    ["200911", "11 / 2009", "Fiscal 2009"],
    ...
]
...
for(var key in salesWeeks)
{
    arr.push(
        "<option value=\"" + salesWeeks[key][0] + "\">" +
        salesWeeks[key][1] + " (" + salesWeeks[key][2] + ")" +
        "<\/option>"
    );
}

würden Sie besser bedienen denke ich (zu denen, die in irgendeiner Form Art befürwortete, wird der Auftrag bereits definiert - warum wollen Sie zusätzliche Arbeit tun)

@curtainDog: NEIN! NEIN! Mit „für .. in“ mit Array-Objekten in JavaScript ist schlecht - der gesamte Punkt des meisten der hier die Antworten ist, dass „für .. in“ bietet keine Garantie für jede Bestellung. Darüber hinaus „für .. in“ Eigenschaften von einem Objekt Konstruktor Prototyp greift und wird nicht nicht vorhandene Schlüssel iterieren.

@Samnan: Die Spezifikation sagt einfach, dass Iterationsreihenfolge nicht gewährleistet ist; Dies bedeutet, dass Browser ist frei in sortierter Reihenfolge, in der Reihenfolge der Einfügung in zufälliger Reihenfolge zu durchlaufen, oder aber sonst sie können. Es ist wie eine Hash-Tabelle -. Betrachten Sie es als zufällig, auch wenn es in einigen offensichtlich kommen geschieht

Ich bin ziemlich sicher, dass die meisten Browser für „for..in“ Look mit Array-Objekten und in numerischer Reihenfolge durchlaufen, so dass die Dinge nicht brechen; Allerdings ist es nicht wirklich tun, was die meisten Leute, die es auf diese Weise denken, verwenden es tut, und es sollte vermieden werden, wenn Sie speziell benötigen Objekt -Typ Iteration.

Es ist keine wirklich gute Praxis, aber ...

Wenn Sie ein Leerzeichen auf den Wert Chrom hinzufügen wird eine Nummer nicht als Wert und wird sie nicht nach Wert sortiert werden.

Beispiel:

<select>
  <option value=" 3">Third</option>
  <option value=" 1">First</option>
  <option value=" 2">Second</option>
</select>

Die gute Seite ist, dass Sie nicht zu addieren und dann alphabetische Zeichen von ID entfernen, wie jemand vorgeschlagen (kann mich nicht erinnern, ob in diesem oder anderen Post mit ähnlichen Frage), könnten Sie leicht schneiden, aber die meisten der Zeit der Raum wird einfach ignoriert, und wenn Sie diejenigen, auf eine andere Datei werden sie einfach sehen den integer-Wert nicht der Raum veröffentlichen oder bekommen.

Im Gegensatz zu allen anderen Antworten, es ist sicherlich ein Fehler in CHROME

Der Grund:

Wenn die Datenstruktur wie Barry ein Papiersack ist, sagte dann:

Die Werte sollten immer randimized werden. Dies ist nicht der Fall in Chrom

Wenn die Datenstruktur sequentiell dann:

Die Werte sollten in der Reihenfolge, in der sie zu der Struktur hinzugefügt wird

Während anderer Browser des zweiten Ansatz folgen, Chrom folgt weder, und es gibt immer noch keine Erklärung, was ist die Sortierreihenfolge Chrom für die Datenstruktur bildet, während auf sie zugegriffen wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top