Domanda

ho notato che certo codice che valuta che taglie pattino per un sito e li sullo schermo uscite e-commerce è rovinare l'ordine in Chrome.

JSON dato può essere:

{
  "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"]
}

... che incrementi dimensioni a metà.

Al momento della conversione in un oggetto e l'iterazione se le chiavi, l'ordine naturale viene rispettato ed essi escono come:

  

7, 7.5, 8, 8.5, ecc.

Ma in Chrome solo, le chiavi che 'look' come cifra tonda sempre vengono fuori dal primo oggetto, quindi l'uscita di un ciclo for ... in è:

  

7, 8, 9, 7.5, 8.5, 9.5 ...

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

Ecco il banco di prova: https://jsfiddle.net/wcapc46L/1/

E 'colpisce solo numeri interi, sembra Webkit / Blink hanno un'ottimizzazione che preferisce Proprietà dell'oggetto che sono numerici, forse è a che fare con Branch Prediction o qualsiasi altra cosa.

se si inserisce le chiavi degli oggetti con qualsiasi personaggio, l'ordine rimane inalterata e funziona come previsto - FIFO

Credo Ricordo di aver letto che non ci sono garanzie dell'ordine di proprietà di un oggetto, ma allo stesso tempo, questo è fastidioso per l'estrema e causerebbe una notevole quantità di sforzo nel fissare per soli cromo utenti.

Tutte le idee? è questo probabilmente un bug che andranno fisso?

modifica Inoltre, ora ho scoperto questo come un problema sul tracker v8 bug:

http://code.google.com/p/v8 / temi / dettaglio? id = 164

appare come Blink non vogliono risolvere il problema e rimarrà l'unico browser che lo farà.

  

Aggiorna qualunque hash table ottimizzazione webkit / batter aveva, ora ha fatto la sua strada in gecko (FF 27.0.1) - http://jsfiddle.net/9Htmq/ risultati in 7,8,9,7.5,8.5,9.5. applicando _ alla consegna delle chiavi restituisce il corretto ordine / previsto.

     

Aggiornamento 2017 Le persone sono ancora upvoting e la modifica di questo modo - non sembra influenzare Map / WeakMap, Set etc (come dimostrato con l'esempio principale aggiornato)

È stato utile?

Soluzione

E 'il modo in cui le maniglie V8 Array Associativi. Un problema noto emissione 164 ma segue la specifica così è contrassegnata 'funziona come previsto'. Non c'è un ordine necessario per il collegamento in cascata array associativi.

Una soluzione semplice è quella di valori numerici precedere con le lettere per esempio:. 'size_7':['9149','9139'] etc

Lo standard cambierà nel prossimo ECMAScript spec costringendo [CHROME] sviluppatori per cambiare questo.

Altri suggerimenti

Sembrerebbe che Chrome sta trattando il integer stringa come se fosse un tipo numerico quando usato come un nome di indice / struttura.

Credo che fare affidamento sulla realizzazione Javascript per preservare l'ordine di ciò che, in alcuni casi, è proprietà degli oggetti, e in altri casi (certamente con Chrome) indici di array, è palesemente un approccio pericoloso e ordine di enumerazione è probabilmente non definiti nelle specifiche. Vorrei suggerire di aggiungere una proprietà aggiuntiva al JSON che indica un tipo di ordinamento:

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

che sei stato trattato come stringhe perché sono stringhe. Il mio miglior suggerimento sarebbe quello di utilizzare lo stesso "di precisione" in tutte le vostre chiavi.

{"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"]}

Quindi, "8.0" invece di "8", ecc.

Anche in questo caso, non ci sono garanzie, ma è più probabile che faranno escono nello stesso ordine.

Per una migliore garanzia, eseguire un ordinamento basato sui tasti, mettendo i valori in una matrice in modo ordinato.

Quando l'iterazione sulle proprietà di un oggetto, l'ordine è specificato nella specifica ECMAScript come essere indefinito e qualsiasi ordine si può avere osservato in qualche ambiente non dovrebbe essere invocata. Se avete bisogno di ordine, utilizzare un Array.

Non credo che si può chiamare questo un bug. Come dici tu stesso, non v'è alcuna GARANZIA su come le proprietà di un oggetto sono ordinati.

Ho trovato un lavoro facile in giro con underscore.js

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

Yay! myArray è tornato a l'ordine corretto in tutti i browser.

Le mie chiavi erano troppo importante per me per convertirli in stringhe. Invece ho creato un altro array che ha appena mantenuto l'ordine delle chiavi.

<?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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top