質問: object.tojson(user2); alert(eq); // gives true
回答: es3でコメントしたソリューションを以下に示します(コードの後に詳細を記載):object.equals = function( x, y ) { if ( x === y ) return true; // if both x and y are null or undefined and exactly the same if ( ! ( x instanceof object ) || ! ( y instanceof object ) ) return false; // if they are not strictly equal, they both need to be objects if ( x.constructor !== y.constructor ) return false; // they must have the exact same prototype chain, the closest we can do is // test there constructor. for ( var p in x ) { if ( ! x.hasownproperty( p ) ) continue; // other properties were tested using x.constructor === y.constructor if ( ! y.hasownproperty( p ) ) return false; // allows to compare x[ p ] and y[ p ] when set to undefined if ( x[ p ] === y[ p ] ) continue; // if they have the same strict value or identity then they are equal if ( typeof( x[ p ] ) !== "object" ) return false; // numbers, strings, functions, booleans must be strictly equal if ( ! object.equals( x[ p ], y[ p ] ) ) return false; // objects and arrays must be tested recursively } for ( p in y ) { if ( y.hasownproperty( p ) && ! x.hasownproperty( p ) ) return false; // allows x[ p ] to be set to undefined } return true; } このソリューションを開発する際に、コーナーケース、効率性に特に注目しましたが、うまく機能するシンプルなソリューションを生み出そうとしました。 javascriptでは、nullとndefinedプロパティとオブジェクトにはプロトタイプチェーンがあり、チェックしないと動作が大きく異なる可能性があります。まず、object.prototypeの代わりにobjectを拡張することを選択しました。これは主にnullが比較のオブジェクトの1つでなかったためです。そして、私はnullは別のものと比較するための有効なオブジェクトであるべきだと信じています。object.prototypeの可能性に関して、他の人が指摘した他の正当な懸念もあります他のコードへの副作用。javascriptがオブジェクトのプロパティをndefinedに設定できるという可能性に対処するために特別な注意が必要です。つまり、値がndefinedに設定されるプロパティが存在します。両方のオブジェクトに同じプロパティがndefinedに設定されており、同等であることを報告します。これは、object.hasownproperty(property_name)を使用してプロパティの存在をチェックすることによってのみ実現できますjson.stringify()はndefinedに設定されたプロパティを削除するため、このフォームを使用した比較では、値に設定されたプロパティは無視されますndefined。関数は、同じコードだけでなく同じ参照を共有する場合にのみ等しいと見なされる必要があります。これは、これらの関数のプロトタイプが考慮されないためです。そのため、コード文字列を比較しても、同じプロトタイプオブジェクトがあることを保証できません。2つのオブジェクトは、同じプロパティだけでなく、同じプロトタイプチェーンを持っている必要があります。これは、両方のオブジェクトのconstructorecmascript 5では、object.getprototypeof()を使用して実際のプロトタイプをテストできます。一部のwebブラウザーは、同じことを行う_proto_プロパティも提供します。上記のコードの改善点利用可能な場合はいつでもこれらの方法のいずれかを使用できます。2は"2.0000"とは見なされず、falseは等しいと見なされる必要があるため、ここでは厳密な比較を使用しますto null、ndefined、または。効率を考慮すると、できるだけ早くプロパティの同等性を比較することになります。次に、それが失敗した場合にのみ、typeofこれらのプロパティを探します。速度の向上は、多数のスカラープロパティを持つ大きなオブジェクトで重要になる可能性があります。2つのループは必要ありません。1つ目は左側のオブジェクトのプロパティをチェックし、2つ目は右側のプロパティをチェックし、存在のみ(値ではない)を確認し、ndefined値。全体的に、このコードはわずか16行のコード(コメントなし)でほとんどのコーナーケースを処理します。更新(2015年8月13日)。 value_equals() 関数がより高速で、nanや0などの0以外の適切なコーナーケースを適切に処理するため、より良いバージョンを実装しました、オプションでオブジェクトのプロパティの順序を強制し、 toubkal プロジェクトテストスイートの一部として 100自動化テスト を超える数の循環参照をテストします。