[解決済み] JavaScriptでのオブジェクト比較 [重複]
2022-03-15 09:31:59
質問
JavaScriptでオブジェクトを比較するのに最適な方法は何ですか?
例
var user1 = {name : "nerd", org: "dev"};
var user2 = {name : "nerd", org: "dev"};
var eq = user1 == user2;
alert(eq); // gives false
知っている 2つのオブジェクトが全く同じオブジェクトを参照している場合、それらは等価である。 しかし、同じ属性の値を持っているかどうかを確認する方法はありますか?
次の方法でうまくいくのですが、これしかないのでしょうか?
var eq = Object.toJSON(user1) == Object.toJSON(user2);
alert(eq); // gives true
解決方法は?
残念ながら、完璧な方法はありません。
_proto_
を再帰的に実行し、すべての非列挙型プロパティにアクセスすることができますが、これは Firefox でのみ動作します。
ですから、私ができることは、使用シナリオを推測することです。
1)高速かつ限定的であること。
内部にメソッドやDOMノードを持たないシンプルなJSONスタイルのオブジェクトがある場合に有効です。
JSON.stringify(obj1) === JSON.stringify(obj2)
プロパティの順序は重要であるため、このメソッドは以下のオブジェクトに対して false を返します。
x = {a: 1, b: 2};
y = {b: 2, a: 1};
2)遅い、汎用性が高い。
プロトタイプを掘り下げることなくオブジェクトを比較し、次にプロパティの投影を再帰的に比較し、さらにコンストラクタを比較します。
これは、ほぼ正しいアルゴリズムです。
function deepCompare () {
var i, l, leftChain, rightChain;
function compare2Objects (x, y) {
var p;
// remember that NaN === NaN returns false
// and isNaN(undefined) returns true
if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
return true;
}
// Compare primitives and functions.
// Check if both arguments link to the same object.
// Especially useful on the step where we compare prototypes
if (x === y) {
return true;
}
// Works in case when functions are created in constructor.
// Comparing dates is a common scenario. Another built-ins?
// We can even handle functions passed across iframes
if ((typeof x === 'function' && typeof y === 'function') ||
(x instanceof Date && y instanceof Date) ||
(x instanceof RegExp && y instanceof RegExp) ||
(x instanceof String && y instanceof String) ||
(x instanceof Number && y instanceof Number)) {
return x.toString() === y.toString();
}
// At last checking prototypes as good as we can
if (!(x instanceof Object && y instanceof Object)) {
return false;
}
if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
return false;
}
if (x.constructor !== y.constructor) {
return false;
}
if (x.prototype !== y.prototype) {
return false;
}
// Check for infinitive linking loops
if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
return false;
}
// Quick checking of one object being a subset of another.
// todo: cache the structure of arguments[0] for performance
for (p in y) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
}
else if (typeof y[p] !== typeof x[p]) {
return false;
}
}
for (p in x) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
}
else if (typeof y[p] !== typeof x[p]) {
return false;
}
switch (typeof (x[p])) {
case 'object':
case 'function':
leftChain.push(x);
rightChain.push(y);
if (!compare2Objects (x[p], y[p])) {
return false;
}
leftChain.pop();
rightChain.pop();
break;
default:
if (x[p] !== y[p]) {
return false;
}
break;
}
}
return true;
}
if (arguments.length < 1) {
return true; //Die silently? Don't know how to handle such case, please help...
// throw "Need two or more arguments to compare";
}
for (i = 1, l = arguments.length; i < l; i++) {
leftChain = []; //Todo: this can be cached
rightChain = [];
if (!compare2Objects(arguments[0], arguments[i])) {
return false;
}
}
return true;
}
既知の問題(まあ、優先順位は非常に低いので、おそらく気づくことはないでしょう)。
- プロトタイプの構造が異なるが、投影が同じであるオブジェクト
- 関数は、同じテキストを持つが、異なるクロージャを参照することがあります。
テストです。 はテストを通過します。 2つのJavaScriptオブジェクトの等質性を判断する方法は? .
関連
-
Vueのイベント処理とイベントモディファイアの解説
-
[解決済み】ExpressJS - throw er Unhandled errorイベント
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] JavaScriptのオブジェクトが空であることをテストするにはどうすればよいですか?
-
[解決済み] JavaScriptのオブジェクトにキーが存在するかどうかをチェックする?
-
[解決済み】未定義のオブジェクトプロパティを検出する
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
要素ツリー制御によるvueTreeテーブル
-
vue+webrtc(Tencent cloud)ライブ機能の実践を実現するために
-
Vueでルートネスティングを実装する例
-
Vueのフォームイベントのデータバインディングの説明
-
[解決済み】React - uncaught TypeError: 未定義のプロパティ 'setState' を読み取れない
-
[解決済み】"フォームが接続されていないため、フォームの送信がキャンセルされました "というエラーの取得について
-
[解決済み】gulp anythingを実行するたびに、アサーションエラーが発生します。- タスク関数を指定する必要があります
-
[解決済み】React - TypeError: 未定義のプロパティ 'props' を読み取ることができない。
-
フロントエンド非同期(アシンク)ソリューション(全ソリューション)
-
[解決済み] 2つのJavaScriptオブジェクトの等質性を判断する方法は?