for...in ステートメントの反復順序に関する質問と、その順序は信頼できないという警告を見ました。現在のノードと訪問したノードの反復と追跡は内部でどのように行われ、JavaScript エンジン間でどのように異なるのでしょうか?
2 に答える
MDN ドキュメントからfor...in
(強調を追加):
オブジェクトの列挙可能なプロパティを任意の順序で反復処理します。
内部の詳細は JavaScript エンジンによって異なり、特定のエンジンのバージョンによっても異なる可能性が高いと確信しています。多くのエンジンでは、ある種のハッシュ テーブルの実装によって行われていると思います。ハッシュ関数は、ハッシュ テーブルが大きくなるにつれてキーの順序を変更するため、エンジンなどを変更することなく、新しいプロパティを追加するだけで、たとえばプロパティa
とプロパティの相対的な順序を変更できます。b
c
Object.keys()
との実装はObject.defineProperties
の動作を模倣する必要があるようですfor...in
:
実装が for-in ステートメントの列挙の特定の順序を定義する場合、このアルゴリズムのステップ 5 で同じ列挙順序を使用する必要があります。
ので、参考にしてください。
演算子はdelete
物事を複雑にすることもあります:
プロパティを列挙するメカニズムと順序 (最初のアルゴリズムのステップ 6.a、2 番目のアルゴリズムのステップ 7.a) は指定されていません。列挙されているオブジェクトのプロパティは、列挙中に削除される場合があります。列挙中にまだ訪問されていないプロパティが削除された場合、そのプロパティは訪問されません。列挙中に列挙されているオブジェクトに新しいプロパティが追加された場合、新しく追加されたプロパティがアクティブな列挙でアクセスされるとは限りません。プロパティ名は、列挙内で複数回アクセスしてはなりません。
プロトタイプ チェーン内の衝突の名前は次のとおりです。
オブジェクトのプロパティの列挙には、そのプロトタイプのプロパティ、およびプロトタイプのプロトタイプなどを再帰的に列挙することが含まれます。ただし、プロトタイプ チェーン内の以前のオブジェクトに同じ名前のプロパティがあるため、プロトタイプのプロパティは「シャドウ」されている場合は列挙されません。[[Enumerable]] 属性の値は、プロトタイプ オブジェクトのプロパティがプロトタイプ チェーンの前のオブジェクトによってシャドウされているかどうかを判断するときに考慮されません。
参考文献