Frage

ich diesen bestimmten Code bemerkt, dass einige Schuhgrößen für eine E-Commerce-Website und gibt sie auf dem Bildschirm ausgewertet wird, um die Reihenfolge, in Chrome vermasselt.

JSON gegeben werden kann:

{
  "7": ["9149", "9139", "10455", "17208"],
  "7.5": ["9140", "9150", "10456", "17209"],
  "8": ["2684", "9141", "10457", "17210"],
  "8.5": ["9142", "10444", "10458", "17211"],
  "9": ["2685", "9143", "10459", "17212"],
  "9.5": ["10443", "9144", "10460", "17213"]
}

... die Schritte Größen in Hälften.

Bei der Umwandlung in ein Objekt und Iterieren obwohl der Schlüssel, die natürliche Ordnung eingehalten wird und sie kommt wie:

7, 7.5, 8, 8.5 etc.

Aber in Chrome nur, Schlüssel, dass 'Look' wie runde Zahlen immer kommen aus dem Objekt zuerst, so Ausgabe eines für ... in Schleife ist:

7, 8, 9, 7,5, 8,5, 9,5 ...

Object.keys(sizes); // ["7", "8", "9", "7.5", "8.5", "9.5"]

Hier ist der Testfall: https://jsfiddle.net/wcapc46L/1/

Es wirkt sich nur auf ganze Zahlen, scheint wie Webkit / Blink eine Optimierung haben, dass bevorzugt Objekteigenschaften, die numerisch sind, vielleicht ist es mit Sprungvorhersage oder was auch immer zu tun.

Wenn Sie die Objektschlüssel mit einem beliebigen Zeichen Präfix, bleibt die Reihenfolge nicht betroffen und funktioniert wie beabsichtigt - FIFO

Ich glaube, ich erinnere lesen, dass es keine Garantien in der Größenordnung von Eigenschaften eines Objekts, aber zur gleichen Zeit, dann ist dies der extremen ärgerlich und verursachen würde einen erheblichen Aufwand in sie allein für Chrome-Nutzer zu fixieren.

Irgendwelche Ideen? ist dies wahrscheinlich ein Fehler, die behoben werden erhalten?

Bearbeiten zusätzlich habe ich nun dies als ein Problem auf dem v8 Bug-Tracker entdeckt:

http://code.google.com/p/v8 / Themen / detail? id = 164

Sieht aus wie Blink nicht wollen, dies zu beheben und wird der einzige Browser bleiben, die es tun wird.

Update , was Hash-Tabelle Optimierung webkit / blink hatte, hat nun seinen Weg in Gecko (FF 27.0.1) - http://jsfiddle.net/9Htmq/ Ergebnisse in 7,8,9,7.5,8.5,9.5. _ vor den Tasten gibt die richtige / erwartete Reihenfolge anwenden.

Update 2017 Die Menschen sind immer noch upvoting und bearbeite diese so - es ist nicht Map / WeakMap zu beeinflussen scheint, Set usw. (wie durch aktualisierte Haupt Beispiel gezeigt)

War es hilfreich?

Lösung

Es ist die Art und Weise v8 Griffe Arrays assoziativ. Ein bekanntes Problem Ausgabe 164 aber es folgt die Spezifikation so markiert ‚arbeitet nun wie vorgesehen.‘ Es ist keine erforderlich, um durch assoziative Arrays für Looping.

Eine einfache Abhilfe ist zu precede Zahlenwerten mit den Buchstaben z. 'size_7':['9149','9139'] etc

Der Standard wird in der nächsten ECMAScript-Spezifikation zwingen [Chrom] Entwickler ändern, dies zu ändern.

Andere Tipps

Es scheint, dass Chrome ist die Behandlung der integer string, als wäre es ein numerischer Typ, wenn als Index / Eigenschaftsnamen verwendet.

Ich denke, auf der JavaScript-Implementierung verlassen, um die Reihenfolge von dem, was in einigen Fällen zu erhalten, Objekteigenschaften sind, und in anderen Fällen (sicherlich mit Chrom) Array-Indizes, ist nachweislich ein unsicherer Ansatz und die Reihenfolge der Aufzählung wird wahrscheinlich nicht definiert in der spec. Ich würde vorschlagen, eine zusätzliche Eigenschaft zum JSON hinzufügen, die eine Sortierreihenfolge angibt:

{
    "7":{"sortOrder":1,"data":["9149","9139","10455","17208"]},
    "7.5":{"sortOrder":2,"data":["9140","9150","10456","17209"]}
    //etc
}

Sie sind zu werden als Zeichenfolgen behandelt, weil sie sind Saiten. Mein bester Vorschlag die gleiche „Präzision“ in allen Ihren Schlüsseln zu verwenden wäre.

{"7.0":["9149","9139","10455","17208"],"7.5":["9140","9150","10456","17209"],"8.0":["2684","9141","10457","17210"],"8.5":["9142","10444","10458","17211"],"9.0":["2685","9143","10459","17212"],"9.5":["10443","9144","10460","17213"]}

Also, "8.0" anstelle von "8", etc.

Auch dann gibt es keine Garantien, aber es ist wahrscheinlicher, dass sie in der gleichen Reihenfolge würden kommen.

Für eine bessere Garantie, führen Sie eine Art basierend auf den Tasten, um die Werte in ein Array in der sortierten Ordnung zu bringen.

Wenn Iterieren über die Eigenschaften eines Objektes, die Reihenfolge, in der ECMAScript-Spezifikation angegeben wird als nicht definiert ist und beliebiger Reihenfolge in einem gewissen Umfeld beobachtet haben können, sollten sich nicht darauf verlassen. Wenn Sie bestellen möchten, verwenden Sie einen Array.

Ich glaube nicht, dass Sie dies einen Fehler nennen. Wie Sie selbst sagen, es gibt keine Garantee auf, wie sich die Eigenschaften eines Objekts sortiert werden.

fand ich eine einfache Arbeit um Underscore.js mit

myArray = _.sortBy(myArray, function(num){ return Math.ceil(num); });

Yay! arr ist wieder in die richtige Reihenfolge, in allen Browsern.

Meine Tasten waren zu wichtig für mich, sie in Strings zu konvertieren. Stattdessen habe ich ein anderes Array, das nur die Reihenfolge der Tasten beibehalten.

<?php 
$origArray = valueReturnedFromFunction();
$preservedOrder = array_keys($origArray);
?>
<script>
var origArray = <?php echo json_encode($origArray)?>;
var preservedOrder = <?php echo json_encode($preservedOrder )?>;

for(i in preservedOrder){
    var item = origArray[i];
    ...
}
</script>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top