Question

D'accord, sur une page Web, j'ai un objet JavaScript que j'utilise comme tableau associatif. Cela existe de manière statique dans un bloc de script lors du chargement de la page:

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

L'ordre des paires clé / valeur est intentionnel, car je transforme l'objet en une zone de sélection HTML telle que celle-ci:

<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>

... avec un code qui ressemble à ceci (extrait d'une fonction):

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("");

Tout cela fonctionne bien dans IE, FireFox et Opera.

Cependant, dans Chrome, l'ordre est très bizarre:

<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>

REMARQUE: Cette commande, bien que bizarre, ne change pas lors des actualisations suivantes. C'est toujours dans cet ordre.

Alors, que fait Chrome? Une optimisation dans la façon dont elle traite la boucle?

En premier lieu, ai-je tort de me fier à l'ordre dans lequel les paires clé / valeur sont déclarées dans un tableau associatif any ?

Je n’en avais jamais posé la question auparavant, j’imaginais que l’ordre resterait, car cette technique a toujours fonctionné pour moi dans les autres navigateurs. Mais je suppose que je ne l’ai jamais vu affirmer nulle part que la commande est garantie. Peut-être que ce n'est pas?

Toute idée serait géniale. Merci.

Était-ce utile?

La solution

Pensez à un tableau associatif comme à un sac en papier dans lequel toutes les paires clé-valeur sont placées. Lorsque vous mettez votre main dans le sac pour regarder les paires (comme avec le for ... en boucle), l'ordre dans lequel vous les rencontrez est à toutes fins pratiques aléatoire.

Si vous souhaitez les voir dans un ordre spécifique, vous devez extraire les clés dans un tableau et le trier. Parcourez ensuite le tableau en utilisant les clés rencontrées pour indexer dans le tableau associatif.

Autres conseils

L'ordre dans lequel les éléments sont stockés dans un tableau associatif n'est pas garanti. Vous devrez trier explicitement votre sortie.

Comme le disent les autres réponses, l'ordre dans lequel les propriétés d'un objet sont itérées n'est pas défini dans la spécification, même si les principaux navigateurs les répètent tous dans l'ordre défini.

Chrome les énumérera également dans l'ordre si toutes les propriétés de l'objet contiennent des valeurs primitives. John Resig donne plus de détails sur le comportement de Chrome ici (sous "pour l'ordre des boucles"): http://ejohn.org/blog/javascript-in-chrome/

Comme indiqué, le comportement de Chrome est parfaitement valide.

C’est un bon exemple de cas où une réflexion orientée objet peut être utile. Voulez-vous vraiment un tableau associatif ou juste une liste d'objets?

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>"
    );
}

vous servirait mieux, je pense (pour ceux qui préconisent une sorte de tri, l'ordre est déjà défini - pourquoi voulez-vous faire un travail supplémentaire?)

@curtainDog: NO! NON! Utilisation de & # 8220; pour .. dans & # 8221; avec des objets Array en JavaScript est mauvais - l’essentiel de la plupart des réponses est que & # 8220; pour .. dans & # 8221; ne garantit aucune commande. De plus, & # 8220; pour .. dans & # 8221; récupérera les propriétés du prototype du constructeur de l'objet et ne parcourra pas les clés inexistantes.

@Samnan: La spécification dit simplement que l'ordre des itérations n'est pas garanti; cela signifie que les navigateurs sont libres d’itérer dans un ordre trié, dans l’ordre d’insertion, dans un ordre aléatoire ou autrement. C’est comme une table de hachage. Considérez-la comme aléatoire, même si elle apparaît dans un ordre apparent.

Je suis assez sûr que la plupart des navigateurs recherchent & # 8220; for..in & # 8221; avec des objets Array et effectuez une itération numérique afin que les choses ne se cassent pas; Toutefois, ce que la plupart des utilisateurs pensent de la sorte, ne le fait pas vraiment, et cela doit être évité sauf si vous avez spécifiquement besoin d'une itération de type objet .

Ce n'est pas vraiment une bonne pratique mais ...

Si vous ajoutez un espace à la valeur, chrome ne considérera pas la valeur comme un nombre et ne les triera pas par valeur.

Exemple:

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

Le bon côté est que vous ne devez pas ajouter, puis supprimer les caractères alphabétiques de l'ID, comme le suggère quelqu'un (ne vous souvenez pas si dans cet article ou un autre avec une question similaire), vous pouvez facilement le couper, mais la plupart du temps, l’espace est simplement ignoré et si vous postez ou transférez ceux-ci dans un autre fichier, ils verront simplement la valeur entière et non l’espace.

Contrairement à toutes les autres réponses, c’est CERTAINEMENT UN BUG EN CHROME

La raison:

Si la structure de données est un sac en papier, comme l'a dit Barry, alors:

Les valeurs doivent toujours être randimisées. Ce n'est pas le cas en chrome

Si la structure de données est séquentielle, alors:

Les valeurs doivent être dans l'ordre dans lequel elles sont ajoutées à la structure

Tandis que les autres navigateurs suivent la deuxième approche, chrome ne suit pas non plus et il n’ya toujours aucune explication sur l’ordre de tri que chrome installe pour la structure de données lorsqu’elle est utilisée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top