JSON.stringify()でのオブジェクト比較について
経緯
業務でJSON.stringify を使ってオブジェクトを比較しているコードに出会い、 「なぜわざわざ JSON.stringify を使ってオブジェクトを比較するのか?」という疑問があり、気になったので調べてみました。 調べてみると、以下の記事にあたりました。
JavaScriptでのオブジェクト比較をどうするか - Qiita
はじめに オブジェクト同士の比較をするときに、「あ〜普通に等価演算子使えばいいじゃん」と思っていて思うような結果が返って来なかったことがありました。 オブジェクトの比較をどうするか、自分用メモです。 比較するオブジェクト interface BaseObject { ...
この記事の参考元をたどると、下記のJavaScript.infoの記事に行き着いたので、そちらを読んでみました。
オブジェクト参照とコピー
オブジェクト比較における JSON.stringify の役割
JavaScriptでは、オブジェクトを比較する際、参照されているメモリアドレスを比較するため、たとえ値が同じでも異なるオブジェクトとして扱われます。
具体的に、次のようなコードでは false が返されます。
const obj1 = { a: 1 };
const obj2 = { a: 1 };
console.log(obj1 === obj2); // false
このため、オブジェクトの比較を行う際に、JSON.stringifyを使ってオブジェクトを文字列に変換し、その文字列同士を比較するという方法がよく使われるようです。
JSON.stringify を使う際の問題点
ただ、上記の方法には問題があるようで、下記の記事で指摘されていました。
JSON.stringifyをオブジェクトの比較に使うのはあまり推奨されない方法ということです。
オブジェクトの比較に JSON.stringify() を使ってはいけない —— プロパティには順序が無い - Qiita
たまたま動いているコード オブジェクト同士の比較に JSON.stringify() を使う例がそこかしこで見られます。 典型的には、 JSON.stringify(objA) === JSON.stringify(objB) のようなコードです。 オブジェクトの中身を...
いくつかの理由があるようですが、 特に大きな問題はオブジェクトのプロパティの順番が変わる可能性があることだと私は理解しました。 例えば、次のような場合です。
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 2, a: 1 };
console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // false
この例では、obj1とobj2は同じ値を持っていますが、プロパティの順番が異なるため、JSON.stringify では同一として扱われません。
他の手段について
代替の方法として、lodashのisEqualメソッドを使う方法が良さそうです。
また今後追記したいと思います。
KJR020's Blog