Object.keys()
オブジェクトをトラバースするときのプロパティの順序は保証されません。この一文を皮切りに、私たちはObject.keys
どんどん「間違った道」を歩み始めました。
Object.keys
オブジェクトのプロパティの順序は保証されませんか?
私はこの文を疑う姿勢で MDN-Object.keys を確認しました。
Object.keys()
は、 で直接見つかった列挙可能なプロパティに対応する文字列を要素とする配列を返しますobject
。プロパティの順序は、 オブジェクトのプロパティを手動でループすることによって与えられる順序と同じです。
直接の説明はありませんが、手動トラバーサルと同じであるというだけで、MDN-for..in を確認してください。
配列インデックスは整数名を持つ単なる列挙可能なプロパティであり、それ以外の点では一般的なオブジェクト プロパティと同一です。 インデックスが特定の順序で返される という 保証はありません。反復の順序は実装に依存するためです。
for...in
反復の順序はブラウザの実装に依存するため、結論は保証されません。
オブジェクトプロパティの順序を保証する
Object.keys()
オブジェクト プロパティの順序が保証できない場合、オブジェクト プロパティの順序を保証できる他のメソッドが JavaScript にありますか。
ownPropertyKeys
: オブジェクト属性の走査順序を指定します。
簡潔なスタイルの記事を見つけました: ES2015 以降の JavaScript オブジェクトではプロパティの順序が予測可能です。これは、ownPropertyKeys
オブジェクト プロパティの走査順序を定義する JavaScript 内のメソッドについて言及しています。
- 整数のようなキーを昇順で並べたもの
- 挿入順序の通常のキー
- 挿入オーダー内のシンボル
- 混合する場合、順序: 整数のような、通常のキー、シンボル
0
Interget のようなキーには、数値に加えて、昇順で返されるキー タイプ1
も含まれます。通常のキーは、挿入順に返されるタイプです。複数の種類が含まれる場合は、前から整数型キー、通常キー、シンボルの順序に従います。(コンソール出力の順番は同じような気がしますが…)"2"
string
Symbol
Object.getOwnPropertyNames()
内部メソッドに基づいてownPropertyKeys
実装されたメソッドにObject.getOwnPropertyNames
は と が含まれますReflect.ownKeys
。これら 2 つのメソッドはオブジェクト属性の順序を保証します。
Reflect.ownKeys()
Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))
返される結果は、ターゲット オブジェクトに直接ハングされる列挙可能プロパティ、非列挙可能プロパティ、および Symbols プロパティで構成される配列と同等です。ただし、主に互換性を考慮して、この方法はここでは選択されません (ES6 によって提案され、IE ではサポートされていません)。
Object.getOwnPropertyNames()
ターゲット オブジェクトに直接アタッチされている列挙可能プロパティと列挙不可能なプロパティの組み合わせを返します。これは ES5 で提案され、互換性が向上し、IE9+ をサポートします。
手動でObject.keys()
注文を追加する
突然、Object.keys()
返されたオブジェクト属性の配列自体は順序を保証できませんが、返された結果は手動で並べ替えることができます。また、プロジェクト内で遭遇する属性名はすべて通常のキー (文字列型) であり、に置き換えるだけで済みますObject.keys(value).sort()
。
それにしてもローダッシュ…
しかし、同僚に聞いたところ、lodash には次のようなisequal
メソッドがあるとのことです。
2 つの値の間で詳細な比較を実行し、それらが等しいかどうかを判断します。
注:
Object
このメソッドは、配列、配列バッファー、ブール値、日付オブジェクト、エラー オブジェクト、マップ、数値 、オブジェクト、正規表現、セット、文字列、記号、および型付き配列の 比較をサポートします 。Object
オブジェクトは、継承されたものではなく、独自の列挙可能なプロパティによって比較されます。関数と DOM ノードは厳密な等価性によって比較されます===
。
うーん...ここのシーンにぴったりです。
そこで好奇心に駆られてlodashのソースコードを見てみたのですが、isequal
詳細比較ではobject
同じキーに対応する値同士が比較されるため、文字列化の処理がなく、順序も問題ありません。オブジェクト属性の... (これを手動で実装するのは少し複雑ですが、直接使用できるので安全です)
うーん...まあ、最終的には妥協してlodashisequal
メソッドを使用しました。
まとめ
オブジェクト属性の走査は、ループに関してはあいまいな領域でありObject.keys()
、forin
オブジェクト属性の順序は保証されていません。Object.getOwnPropertyNames
組み込みメソッドに基づいてownPropertyKeys
、オブジェクト属性の順序が保証されており、互換性は非常に優れています。 IE9+をサポートします。