30

e コマース サイトで靴のサイズを評価して画面に出力する特定のコードが、Chrome で順序を乱していることに気付きました。

指定できる JSON は次のとおりです。

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

...サイズを半分に増やします。

オブジェクトに変換してキーを反復すると、自然順序が尊重され、次のようになります。

7、7.5、8、8.5など

ただし、Chrome のみでは、丸数字のように「見える」キーは常に最初にオブジェクトから出てくるため、for... in ループの出力は次のようになります。

7、8、9、7.5、8.5、9.5 ...

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

テストケースは次のとおりです: https://jsfiddle.net/wcapc46L/1/

整数にのみ影響します。Webkit / Blink には、数値のオブジェクト プロパティを優先する最適化があるようです。おそらく、分岐予測などに関係しています

オブジェクト キーの前に任意の文字を付けても、順序は影響を受けず、意図したとおりに機能します - FIFO

オブジェクトのプロパティの順序に保証がないことを読んだことを覚えていると思いますが、同時に、これは極端に面倒であり、クロムユーザーだけで修正するにはかなりの労力が必要になります.

何か案は?これはおそらく修正されるバグですか?

さらに編集して、v8バグトラッカーの問題としてこれを発見しました:

https://code.google.com/p/v8/issues/detail?id=164

Blink はこれを修正したくないようで、修正できる唯一のブラウザであり続けるでしょう。

ハッシュテーブルの最適化 webkit/blink が持っていたものを更新すると、現在 gecko (FF 27.0.1) に組み込まれています - https://jsfiddle.net/9Htmq/結果は7,8,9,7.5,8.5,9.5. _キーが正しい/予想される順序を返す前に適用します。

update 2017人々はまだこれを支持して編集しているので、Map/などには影響しないようです(更新されたメインの例で示されているように)WeakMapSet

4

7 に答える 7

24

これは、v8 が連想配列を処理する方法です。既知の問題Issue 164ですが、仕様に従っているため、「意図したとおりに機能する」とマークされています。連想配列をループするために必要な順序はありません。

簡単な回避策は、数値の前に文字を付けることです (例:'size_7':['9149','9139']など)。

標準は次の ECMAScript 仕様で変更され、[chrome] 開発者はこれを変更する必要があります。

于 2010-07-06T14:06:54.590 に答える
1

Chromeは、インデックス/プロパティ名として使用される場合、整数型を数値型であるかのように扱っているように見えます。

場合によってはオブジェクトプロパティであり、他の場合(確かにchromeを使用)の配列インデックスの順序を維持するためにJavascript実装に依存することは、明らかに安全でないアプローチであり、列挙の順序はおそらく仕様で定義されていないと思います。並べ替え順序を示すプロパティをJSONに追加することをお勧めします。

{
    "7":{"sortOrder":1,"data":["9149","9139","10455","17208"]},
    "7.5":{"sortOrder":2,"data":["9140","9150","10456","17209"]}
    //etc
}
于 2010-07-06T13:58:55.760 に答える
1

それらは文字列であるため、文字列として扱われています。私の最善の提案は、すべてのキーで同じ「精度」を使用することです。

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

したがって、「8」ではなく「8.0」などです。

それでも、保証はありませんが、同じ順序で出てくる可能性が高くなります。

確実性を高めるには、キーに基づいて並べ替えを実行し、並べ替えられた順序で値を配列に入れます。

于 2010-07-06T14:05:28.633 に答える
1

オブジェクトのプロパティを反復処理する場合、順序は ECMAScript 仕様で未定義として指定されており、一部の環境で観察された可能性のある順序は信頼すべきではありません。注文が必要な場合は、 を使用してArrayください。

于 2010-07-06T14:06:24.250 に答える
0

これをバグとは言えないと思います。あなた自身が言うように、オブジェクトのプロパティがどのようにソートされるかについての保証はありません。

于 2010-07-06T13:59:53.063 に答える