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 を展開する手順 (グラフィック チュートリアル)

推薦する

MySQL トリガー: トリガーの作成と使用

この記事では、例を使用して MySQL トリガーの作成と使用について説明します。ご参考までに、詳細は...

無効にしてHTMLフォーム入力を送信した後にフォーム値が取得されない問題を解決する方法

フォーム入力ボックスの入力をdisable属性に設定して送信すると、入力ボックスの値を取得できなくな...

Node.js を使用して C# のデータ テーブル エンティティ クラス生成ツールを作成する方法

Microsoft は T4 テンプレートを提供していますが、使用するのが非常に難しいと思います。ス...

nginxのデフォルトポートを変更する方法の詳細な説明

まず設定ファイルがどこにあるか調べる nginx.confはどこにありますかこれらのディレクトリを調...

Linux システムコマンドのメモ

この記事では、Linux システム コマンドについて説明します。ご参考までに、詳細は以下の通りです。...

docker コンペ応募でよく使われるコマンドのまとめ

アカウントにログイン DOCKER_REGISTRY=registry.cn-hangzhou.al...

MySQL 外部キー設定方法の例

1. 外部キーの設定方法1. MySQL では、2 つのテーブルを関連付けるために、外部キー (FO...

Vue-cliに基づくコードセットは複数のプロジェクトをサポートします

目次アプリケーションシナリオアイデアプロジェクト構造全体的なプロジェクト構造webpack パッケー...

EclipseにTomcatサーバー設定を追加する方法

1. ウィンドウ -> 設定を選択してEclipseの設定パネルを開きます。 2. 「設定」ウ...

Webpackを使用して複数ページのプログラムを構築するための実装手順

webpack を使用してシングルページのプログラムを構築することは非常に一般的ですが、実際の開発で...

MySQL でデータベースを作成した後、ユーザー 'root'@'%' によるデータベース 'xxx' へのアクセスが拒否される問題を解決する

序文最近、仕事で問題が発生しました。データベースを作成した後、データベースに接続するときにエラーが発...

Flex プログラム Firefox で中国語を入力すると文字化けするバグ

Firefox の下位バージョンでは中国語の文字を入力できず、上位バージョンでは文字化けした文字が表...

SQL IDENTITY_INSERT ケーススタディ

一般的に、データ テーブル内の列を ID 列として設定すると、ID 列の表示値を手動で ID 列に挿...

インラインブロックを使用した複数のdiv間の間隔はプログラミング方法とは異なります

inline-block について学習しているときに、境界線と inline-block を持つ複数...

Mysql は null 値の first/last メソッドの例を実装します

序文MySQL が SQL SELECT コマンドと WHERE 句を使用してテーブルからデータを読...