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.
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.
JavaScript fournit 3 méthodes pour comparer les valeurs :
===
==
Object.is()
FonctionLors 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.
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.
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: 'Batman', realName: 'Bruce Wayne' }; const hero2 = { name: 'Batman', realName: 'Bruce Wayne' }; const hero3 = { name: 'Joker' }; 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: 'Batman', address: { city: 'Gotham' } }; const hero2 = { name: 'Batman', address: { city: 'Gotham' } }; 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.
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 === 'object'; }
第 13 行的 areObjects && !deepEqual(val1, val2)
一旦检查到的属性是对象,则递归调用将会开始验证嵌套对象是否也相等。
现在用 deepEquality()
比较具有嵌套对象的对象:
const hero1 = { name: 'Batman', address: { city: 'Gotham' } }; const hero2 = { name: 'Batman', address: { city: 'Gotham' } }; deepEqual(hero1, hero2); // => true
深度比较函数能够正确地确定 hero1
和 hero2
是否具有相同的属性和值,包括嵌套对象 hero1.address
和 hero2.address
的相等性。
为了深入比较对象,我建议使用Node内置util
模块的 isDeepStrictEqual(object1, object2)
或lodash
库的 _.isEqual(object1, object2)
。
引用相等性(使用 ===
、 ==
或 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!