Maison  >  Article  >  interface Web  >  Plusieurs façons de comparer des objets en JavaScript

Plusieurs façons de comparer des objets en JavaScript

青灯夜游
青灯夜游avant
2020-12-24 17:59:133143parcourir

L'article suivant vous donnera quatre façons de comparer correctement les objets JavaScript. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Plusieurs façons de comparer des objets en JavaScript

Comparer des valeurs brutes en JavaScript est très simple. Utilisez simplement l'un des opérateurs d'égalité disponibles, tels que l'opérateur d'égalité stricte :

'a' === 'c'; // => false
1   === 1;   // => true

Mais les objets ont des données structurées, la comparaison est donc difficile. Dans cet article, vous apprendrez à comparer correctement des objets en JavaScript.

1. Comparaison de référence

JavaScript fournit 3 méthodes pour comparer les valeurs :

  • Opérateur d'égalité stricte===
  • Opérateur d'égalité détendue==
  • Object.is() Fonction

Lors de la comparaison d'objets à l'aide de l'une des méthodes ci-dessus, uniquement lorsque les valeurs comparées sont référencées Lorsque la même instance d'objet est utilisé, le résultat de l'évaluation de la comparaison est true. C'est l'égalité de référence.

Définissons les objets hero1 et hero2 et voyons l'égalité de référence en action :

const hero1 = {
  name: 'Batman'
};
const hero2 = {
  name: 'Batman'
};

hero1 === hero1; // => true
hero1 === hero2; // => false

hero1 == hero1; // => true
hero1 == hero2; // => false

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

hero1 === hero1 est évalué à true à cause des deux opérandes. Les deux pointent vers le même objet exemple hero1.

D'un autre côté, hero1 === hero2 est évalué à false car hero1 et hero2 sont des instances d'objet différentes.

Fait intéressant, le contenu des objets hero1 et hero2 est identique : les deux objets ont une propriété name dont la valeur est 'Batman'. Néanmoins, même en comparant des objets de même structure, le résultat de hero1 === hero2 est false.

L'égalité des références est utile lorsque vous souhaitez comparer les références d'objets plutôt que leur contenu. Mais le plus souvent, vous souhaitez comparer des objets en fonction de leur contenu réel : des propriétés et leurs valeurs, par exemple.

Voyons ensuite comment comparer des objets pour vérifier leur égalité en fonction de leur contenu.

2. Comparaison manuelle

Le moyen le plus simple de comparer des objets par contenu est de lire les propriétés et de les comparer manuellement.

Par exemple, écrivons une fonction spéciale isHeroEqual() pour comparer deux objets héros :

function isHeroEqual(object1, object2) {
  return object1.name === object2.name;
}

const hero1 = {
  name: 'Batman'
};
const hero2 = {
  name: 'Batman'
};
const hero3 = {
  name: 'Joker'
};

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

isHeroEqual() Accédez aux propriétés des deux objets name et comparez leurs valeurs.

Si l'objet comparé a certaines propriétés, je préfère écrire une fonction de comparaison comme isHeroEqual() . De telles fonctions ont de bonnes performances : seuls quelques accesseurs de propriété et opérateurs d'égalité sont impliqués dans la comparaison.

La comparaison manuelle nécessite d'extraire manuellement les propriétés, ce qui ne pose pas de problème pour des objets simples. Cependant, comparer des objets plus grands (ou des objets dont la structure est inconnue) n'est pas pratique car cela nécessite beaucoup de code passe-partout.

Voyons donc comment une comparaison superficielle d’objets peut aider.

3. Comparaison superficielle

Si vous vérifiez des objets avec une comparaison superficielle, vous devez obtenir les listes de propriétés des deux objets (en utilisant Object.keys()), puis les vérifier Si les valeurs d'attribut sont égales.

Le code suivant est une implémentation de comparaison superficielle :

function shallowEqual(object1, object2) {
  const keys1 = Object.keys(object1);
  const keys2 = Object.keys(object2);

  if (keys1.length !== keys2.length) {
    return false;
  }

  for (let index = 0; index < keys1.length; index++) {
    const val1 = object1[keys1[index]];
    const val2 = object2[keys2[index]];
    if (val1 !== val2) {
      return false;
    }
  }

  return true;
}

À l'intérieur de la fonction, keys1 et keys2 contiennent respectivement les noms d'attribut object1 et object2.

parcourt les clés avec for et compare chaque attribut de object1 et object2.

En utilisant une comparaison superficielle, vous pouvez facilement vérifier l'égalité sur des objets avec de nombreuses propriétés :

const hero1 = {
  name: &#39;Batman&#39;,
  realName: &#39;Bruce Wayne&#39;
};
const hero2 = {
  name: &#39;Batman&#39;,
  realName: &#39;Bruce Wayne&#39;
};
const hero3 = {
  name: &#39;Joker&#39;
};

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

shallowEqual(hero1, hero2) renvoie true car les objets hero1 et hero2 ont les mêmes attributs (name et realName), et les mêmes valeurs.

Par contre, puisque hero1 et hero3 ont des propriétés différentes, shallowEqual(hero1, hero3) reviendra false.

Mais les objets en JavaScript peuvent être imbriqués. Les comparaisons superficielles ne fonctionnent pas bien dans ce cas.

Ce qui suit effectue une vérification de comparaison superficielle sur un objet avec des objets imbriqués :

const hero1 = {
  name: &#39;Batman&#39;,
  address: {
    city: &#39;Gotham&#39;
  }
};
const hero2 = {
  name: &#39;Batman&#39;,
  address: {
    city: &#39;Gotham&#39;
  }
};

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

Cette fois, même si les deux objets hero1 et hero2 ont le même contenu, shallowEqual(hero1, hero2) Will revenez également false.

Cela se produit parce que les objets imbriqués hero1.address et hero2.address sont des instances d'objet différentes. Par conséquent, une comparaison superficielle considère hero1.address et hero2.address comme deux valeurs différentes.

La résolution des problèmes liés aux objets imbriqués nécessite une comparaison approfondie.

4. Comparaison profonde

La comparaison profonde est similaire à la comparaison superficielle, sauf que lorsqu'un objet est contenu dans un attribut, une comparaison superficielle récursive sera effectuée sur le comparaison d'objets imbriqués.

Regardez la mise en œuvre de la comparaison approfondie :

function deepEqual(object1, object2) {
  const keys1 = Object.keys(object1);
  const keys2 = Object.keys(object2);

  if (keys1.length !== keys2.length) {
    return false;
  }

  for (let index = 0; index < keys1.length; index++) {
    const val1 = object1[keys1[index]];
    const val2 = object2[keys2[index]];
    const areObjects = isObject(val1) && isObject(val2);
    if (areObjects && !deepEqual(val1, val2) || 
        !areObjects && val1 !== val2) {
      return false;
    }
  }

  return true;
}

function isObject(object) {
  return object != null && typeof object === &#39;object&#39;;
}

第 13 行的 areObjects && !deepEqual(val1, val2)  一旦检查到的属性是对象,则递归调用将会开始验证嵌套对象是否也相等。

现在用 deepEquality() 比较具有嵌套对象的对象:

const hero1 = {
  name: &#39;Batman&#39;,
  address: {
    city: &#39;Gotham&#39;
  }
};
const hero2 = {
  name: &#39;Batman&#39;,
  address: {
    city: &#39;Gotham&#39;
  }
};

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

深度比较函数能够正确地确定 hero1hero2 是否具有相同的属性和值,包括嵌套对象  hero1.address  和 hero2.address 的相等性。

为了深入比较对象,我建议使用Node内置util模块的  isDeepStrictEqual(object1, object2)  或lodash 库的 _.isEqual(object1, object2)

5. 总结

引用相等性(使用  =====Object.is())用来确定操作数是否为同一个对象实例。

手动检查对象是否相等,需要对属性值进行手动比较。尽管这类检查需要手动编码来对属性进行比较,但由于很简单,所以这种方法很方便。

当被比较的对象有很多属性或在运行时确定对象的结构时,更好的方法是使用浅层检查。

如果比较的对象具有嵌套对象,则应该进行深度比较检查。

英文原文地址:https://dmitripavlutin.com/how-to-compare-objects-in-javascript/

作者:Dmitri Pavlutin

译文地址:https://segmentfault.com/a/1190000022913676

更多编程相关知识,请访问:编程入门!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer