JavaScript オブジェクトを比較する 4 つの方法

JavaScript オブジェクトを比較する 4 つの方法

序文

JavaScript でプリミティブ値を比較するのは非常に簡単です。厳密な等価演算子など、利用可能な等価演算子のいずれかを使用します。

'a' === 'c'; // => 偽
1 === 1; // => 真

ただし、オブジェクトには構造化されたデータがあるため、比較はより困難になります。この記事では、JavaScript でオブジェクトを適切に比較する方法を学習します。

参考比較

JavaScript には、値を比較するための 3 つの方法が用意されています。

  • 厳密な等価演算子 ===
  • 緩い等価演算子 ==
  • Object.is() 関数

上記のいずれかの方法を使用してオブジェクトを比較する場合、比較された値が同じオブジェクト インスタンスを参照している場合にのみ、比較は true と評価されます。これは参照等価性です。

オブジェクト hero1 と hero2 を定義して、参照の等価性が実際にどのように機能するかを見てみましょう。

定数ヒーロー1 = {
  名前: 「バットマン」
};
定数hero2 = {
  名前: 「バットマン」
};

hero1 === hero1; // => 真
ヒーロー1 === ヒーロー2; // => 偽

hero1 == hero1; // => 真
ヒーロー1 == ヒーロー2; // => 偽

Object.is(hero1, hero1); // => true
Object.is(hero1, hero2); // => false

両方のオペランドが同じオブジェクト インスタンス hero1 を参照するため、hero1 === hero1 は true と評価されます。

一方、hero1 と hero2 は異なるオブジェクト インスタンスであるため、hero1 === hero2 は false と評価されます。

興味深いことに、hero1 オブジェクトと hero2 オブジェクトの内容は同一です。両方のオブジェクトに、値が「Batman」である name プロパティがあります。ただし、hero1 === hero2 は、同じ構造のオブジェクトを比較する場合でも false と評価されます。

参照の等価性は、オブジェクトの内容ではなく参照を比較する場合に便利です。しかし、多くの場合、オブジェクトの実際の内容、つまりプロパティとその値を比較する必要があります。

次に、オブジェクトの内容に基づいてオブジェクトを比較する方法を見てみましょう。

手動比較

オブジェクトをコンテンツ別に比較する最も簡単な方法は、プロパティを読み取って手動で比較することです。

たとえば、2 つのヒーロー オブジェクトを比較する特別な関数 isHeroEqual() を記述してみましょう。

関数 isHeroEqual(オブジェクト1, オブジェクト2) {
  object1.name === object2.name を返します。
}

定数ヒーロー1 = {
  名前: 「バットマン」
};
定数hero2 = {
  名前: 「バットマン」
};
定数hero3 = {
  名前: 「ジョーカー」
};

isHeroEqual(hero1, hero2); // => true
isHeroEqual(hero1, hero3); // => false

isHeroEqual() は両方のオブジェクトの name プロパティにアクセスし、その値を比較します。

比較するオブジェクトに何らかのプロパティがある場合は、isHeroEqual() のような比較関数を記述することをお勧めします。このタイプの関数はパフォーマンスが良好です。比較には少数のプロパティ アクセサーと等価演算子のみが関与します。

手動比較ではプロパティを手動で抽出する必要がありますが、単純なオブジェクトの場合は問題になりません。ただし、大きなオブジェクト (または構造が不明なオブジェクト) を比較する場合は、大量の定型コードが必要になるため、便利ではありません。

それでは、オブジェクトの浅い比較がどのように役立つかを見てみましょう。

浅い比較

浅い比較を使用してオブジェクトをチェックする場合は、両方のオブジェクトのプロパティのリストを取得し (Object.keys() を使用)、それらのプロパティ値が等しいかどうかを確認する必要があります。

次のコードは浅い比較の実装です。

関数 shallowEqual(オブジェクト1, オブジェクト2) {
  定数keys1 = Object.keys(object1);
  定数keys2 = Object.keys(object2);

  キー1の長さがキー2の長さと等しい場合
    false を返します。
  }

  for (let index = 0; index < keys1.length; index++) {
    定数val1 = object1[keys1[index]];
    val2 = object2[keys2[index]];
    (val1 !== val2)の場合{
      false を返します。
    }
  }

  true を返します。
}

関数内では、keys1 と keys2 はそれぞれ object1 と object2 のプロパティの名前を含む配列です。

for ループを使用してキーを反復処理し、object1 と object2 の各プロパティを比較します。

浅い比較を使用すると、多くのプロパティを持つオブジェクトの等価性を簡単にチェックできます。

定数ヒーロー1 = {
  名前:「バットマン」
  本名:「ブルース・ウェイン」
};
定数hero2 = {
  名前:「バットマン」
  本名:「ブルース・ウェイン」
};
定数hero3 = {
  名前: 「ジョーカー」
};

shallowEqual(hero1, hero2); // => true
shallowEqual(hero1, hero3); // => false

shallowEqual(hero1, hero2)は、hero1とhero2のオブジェクトが

属性(nameとrealName)は同じで、値も同じです。

一方、hero1 と hero3 はプロパティが異なるため、shallowEqual(hero1, hero3) は false を返します。

しかし、JavaScript のオブジェクトはネストできます。この場合、浅い比較はうまく機能しません。

以下は、ネストされたオブジェクトを持つオブジェクトに対して浅い比較チェックを実行します。

定数ヒーロー1 = {
  名前:「バットマン」
  住所:
    都市: 'ゴッサム'
  }
};
定数hero2 = {
  名前:「バットマン」
  住所:
    都市: 'ゴッサム'
  }
};

shallowEqual(hero1, hero2); // => false

今回は、2 つのオブジェクト hero1 と hero2 の内容が同じであるにもかかわらず、shallowEqual(hero1, hero2) は false を返します。

これは、ネストされたオブジェクト hero1.address と hero2.address が異なるオブジェクト インスタンスであるために発生します。したがって、浅い比較では、hero1.address と hero2.address は 2 つの異なる値とみなされます。

ネストされたオブジェクトの問題を解決するには、詳細な比較が必要です。

徹底比較

ディープ比較は、シャロー比較に似ていますが、プロパティにオブジェクトが含まれている場合は、ネストされたオブジェクトに対して再帰的なシャロー比較が実行される点が異なります。

ディープ比較の実装を見てみましょう。

関数 deepEqual(オブジェクト1, オブジェクト2) {
  定数keys1 = Object.keys(object1);
  定数keys2 = Object.keys(object2);

  キー1の長さがキー2の長さと等しい場合
    false を返します。
  }

  for (let index = 0; index < keys1.length; index++) {
    定数val1 = object1[keys1[index]];
    val2 = object2[keys2[index]];
    定数 areObjects = isObject(val1) && isObject(val2);
    if (areObjects && !deepEqual(val1, val2) || 
        !areObjects && val1 !== val2) {
      false を返します。
    }
  }

  true を返します。
}

関数isObject(オブジェクト) {
  戻りオブジェクト != null && typeof object === 'object';
}

13 行目 areObjects && !deepEqual(val1, val2) チェックされたプロパティがオブジェクトになると、再帰呼び出しが開始され、ネストされたオブジェクトも等しいかどうかが検証されます。

次に、deepEquality() を使用してオブジェクトをネストされたオブジェクトと比較します。

定数ヒーロー1 = {
  名前:「バットマン」
  住所:
    都市: 'ゴッサム'
  }
};
定数hero2 = {
  名前:「バットマン」
  住所:
    都市: 'ゴッサム'
  }
};

deepEqual(hero1, hero2); // => true

ディープ比較関数は、ネストされたオブジェクト hero1.address と hero2.address の等価性を含め、hero1 と hero2 が同じプロパティと値を持っているかどうかを正しく判断します。

オブジェクトの詳細な比較には、Node の組み込みユーティリティ モジュールの isDeepStrictEqual(object1, object2) または lodash ライブラリの _.isEqual(object1, object2) を使用することをお勧めします。

要約する

参照等価性 (===、==、または Object.is() を使用) は、オペランドが同じオブジェクト インスタンスであるかどうかを判断するために使用されます。

オブジェクトの等価性を手動でチェックするには、プロパティ値を手動で比較する必要があります。このタイプのチェックでは、属性を比較するために手動でコーディングする必要がありますが、簡単なので便利です。

比較するオブジェクトに多くのプロパティがある場合、またはオブジェクトの構造が実行時に決定される場合は、浅いチェックを使用する方がよい方法です。

比較するオブジェクトにネストされたオブジェクトがある場合は、詳細な比較チェックを実行する必要があります。

以上がJavaScriptオブジェクトを比較する4つの方法の詳細です。JavaScriptの詳細については、123WORDPRESS.COMの他の関連記事にも注目してください。

以下もご興味があるかもしれません:
  • js で 2 つのオブジェクトを比較する方法の例
  • jsは2つの別々の配列またはオブジェクトの等価性を比較します
  • JS で 2 つの Json オブジェクトが等しいかどうかを比較する方法は? サンプル コード
  • 2つのJsonオブジェクトの値を比較して等しいかどうかを確認するJSの例の詳細な説明
  • jsオブジェクトの比較
  • JavaScript オブジェクト比較実装コード
  • JavaScriptオブジェクトの4つのメソッドの詳細な説明

<<:  JS で列挙をシミュレートする方法

>>:  デスクトップ仮想化を実現するために Hyper-V を展開する手順 (グラフィック チュートリアル)

推薦する

imgタグ間のスペースの問題の詳細な説明

IMG タグの基本分析 HTML5 では、img タグには 4 つの要素があります。 (1) src...

docker で php+nginx+swoole+mysql+redis 環境を構築する方法

オペレーティングシステム: Alibaba Cloud ESC インスタンス centos7.4ソフ...

JavaScript シミュレーション計算機

この記事では、JavaScriptシミュレーション計算機の具体的なコードを参考までに紹介します。具体...

JS 4つの楽しいハッカー背景効果コードを共有する

目次例1例2例3例4例1 <html> <ヘッド> <title>...

シンプルな計算機を実装するためのネイティブ js

この記事の例では、参考までに簡単な計算機を実装するためのjsの具体的なコードを共有しています。具体的...

Vueインスタンスで$refsを使用する際の注意点

開発の過程では、インスタンスの vm.$refs(this.$refs) を使用して、ref で登録...

表示または可視性によってHTML要素を非表示にする

場合によっては、特定の条件に基づいて Web ページ内の HTML 要素を表示するか非表示にするかを...

マウスのドラッグ効果を実現するJavaScript

この記事では、マウスドラッグ効果を実現するためのJavaScriptの具体的なコードを参考までに紹介...

Linux で MySQL をインストールする簡単な方法

Linux に MySQL をインストールする方法をオンラインで検索すると、多くの方法が表示されまし...

Linux システム修復モード (シングル ユーザー モード)

目次序文1. シングルユーザーモードでの一般的なバグ修正2. シングルユーザーモードでシステムパスワ...

Vue は better-scroll を使用して水平スクロール方法の例を実現します

1. スクロールの実装原理better-scroll のスクロール原理は、ブラウザのネイティブスクロ...

Tomcat プロセスの CPU 使用率が高い場合のトラブルシューティング記録を記録する

この記事では主にTomcatプロセスを記録し、TCP接続が多すぎることによるCPU使用率の過剰のトラ...

Nginx と Lua を使用した JWT 検証の概要

目次序文Lua スクリプトnignx.conf の設定Dockerfileの設定序文データベースやそ...

ボタンをクリックして画像を切り替える JavaScript

この記事の例では、ボタンをクリックすることで画像を切り替えることを実現するJavaScriptの具体...

Vue を使用してパブリック アカウントの Web ページを開発する方法

目次プロジェクトの背景始めるvue-cliでプロジェクトを作成するモバイル適応についてnormali...