7

わかりました。Web ページで、連想配列として使用している JavaScript オブジェクトを取得しました。これは、ページの読み込み時にスクリプト ブロックに静的に存在します。

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

オブジェクトを次のような HTML 選択ボックスに変換しているため、キーと値のペアの順序は意図的なものです。

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

...次のようなコードを使用します(関数から抜粋):

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

これはすべて、IE、FireFox、および Opera で正常に機能します。

ただし、Chrome では、順序がすべて奇妙になります。

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

注: この順序は奇妙ですが、その後の更新では変更されません。いつもこの順番です。

では、Chrome は何をしているのでしょうか。ループの処理方法の最適化はありますか?

そもそも、キーと値のペアが連想配列で宣言されている順序に依存するのは間違っていますか?

以前は疑問に思ったことはありませんでしたが、この手法は他のブラウザーで常に機能していたため、順序が保持されると思っていました。しかし、注文が保証されているとどこにも述べられているのを見たことがないと思います。そうじゃないかも?

どんな洞察も素晴らしいでしょう。ありがとう。

4

7 に答える 7

10

連想配列は、すべてのキーと値のペアが配置される紙の袋と考えてください。袋に手を入れてペアを見るとき(for ... inループなど)、それらに遭遇する順序は、すべての実用的な目的でランダムです。

それらを特定の順序で表示したい場合は、キーを配列に抽出して並べ替える必要があります。次に、遭遇したキーを使用して連想配列にインデックスを付け、配列全体を歩きます。

于 2009-03-12T22:42:03.503 に答える
8

要素が連想配列に格納される順序は保証されません。出力を明示的にソートする必要があります。

于 2009-03-12T22:33:41.467 に答える
2

他の回答が言うように、主要なブラウザはすべて定義された順序でそれらを反復しますが、オブジェクトのプロパティが反復される順序は仕様で定義されていません。

オブジェクトのすべてのプロパティにプリミティブ値が含まれている場合、Chrome はそれらも順番に列挙します。John Resig が Chrome の動作について詳しく説明しています (「for ループの順序」の下): http://ejohn.org/blog/javascript-in-chrome/

于 2009-03-12T23:10:06.277 に答える
2

それは本当に良い習慣ではありませんが...

値にスペースを追加すると、クロムは値を数値と見なさず、値でソートしません。

例:

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

良い面は、誰かが提案したようにIDにアルファベット文字を追加してから削除する必要がないことです(これまたは同様の質問のある他の投稿で覚えていないでください)。簡単に削除できますが、ほとんどの場合、スペースはちょうどです無視され、それらを別のファイルに投稿または取得すると、スペースではなく整数値が表示されます。

于 2012-07-05T22:08:03.197 に答える
2

指摘したように、Chrome の動作は完全に有効です。

これは、オブジェクト指向の考え方が役立つ良い例です。本当に連想配列が必要ですか、それとも単にオブジェクトのリストが必要ですか?

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

より良いサービスを提供すると思います (ある種の形式を提唱する人にとっては、順序は既に定義されています - なぜ余分な作業をしたいのですか?)

于 2010-05-24T22:20:17.050 に答える
2

@curtainDog: いいえ! いいえ!JavaScript で Array オブジェクトに「for .. in」を使用するのはよくありません。ここでのほとんどの回答の要点は、「for .. in」は順序を保証しないということです。さらに、「for .. in」は、オブジェクトのコンストラクターのプロトタイプからプロパティを取得し、存在しないキーを反復処理しません。

@Samnan:仕様では、反復順序が保証されていないと単純に述べています。これは、ブラウザがソート順、挿入順、ランダム順、またはその他の方法で自由に反復できることを意味します。これは、ハッシュ テーブルのようなものです。たまたま明らかな順序で出てきたとしても、ランダムであると考えてください。

ほとんどのブラウザは、Array オブジェクトで「for..in」を検索し、番号順に反復処理を行って、問題が発生しないようにしていると確信しています。ただし、そのように使用するほとんどの人が思っていることを実際に行っているわけではありません。 object型の反復が特に必要でない限り、避けるべきです。

于 2011-01-23T22:00:14.250 に答える
-3

他のすべての回答とは対照的に、それは確かにCHROMEのバグです

理由:

データ構造が Barry が言ったような紙袋の場合:

値は常にランダム化する必要があります。これはクロムには当てはまりません

データ構造がシーケンシャルの場合:

値は、構造に追加された順序である必要があります

他のブラウザは 2 番目のアプローチに従いますが、chrome はどちらにも従わず、クロムがアクセス中にデータ構造を補う並べ替え順序についての説明はまだありません。

于 2010-09-29T13:44:17.653 に答える