The following article will give you four ways to correctly compare JavaScript objects. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.
#Comparing raw values in JavaScript is very simple. Just use any of the available equality operators, such as the strict equality operator:
'a' === 'c'; // => false 1 === 1; // => true
But objects have structured data, so comparison is difficult. In this article, you will learn how to correctly compare objects in JavaScript.
JavaScript provides 3 methods for comparing values:
===
==
Object.is()
FunctionWhen comparing objects using any of the above methods, the comparison evaluates totrue
only if the compared values refer to the same object instance. This isreference equality.
Let's define objectshero1
andhero2
and see reference equality in 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
evaluates totrue
because both operands point to the same object instancehero1
.
On the other hand,hero1 === hero2
evaluates tofalse
becausehero1
andhero2
are Different object instances.
Interestingly, the contents of thehero1
andhero2
objects are the same: both objects have aname
attribute, and its other The value is'Batman'
. Still, even when comparing objects of the same structure,hero1 === hero2
results infalse
.
Reference equality is useful when you want to compare object references rather than their contents. But more often than not, you want to compare objects based on their actual contents: properties and their values, for example.
Next let’s look at how to compare objects for equality through their contents.
The most straightforward way to compare objects by content is to read the properties and compare them manually.
For example, let us write a special functionisHeroEqual()
to compare two hero objects:
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()
Access both Object's propertiesname
and compare their values.
If the object being compared has some properties, I prefer to write a comparison function likeisHeroEqual()
. Such functions have good performance: only a few property accessors and equality operators are involved in the comparison.
Manual comparison requires manual extraction of properties, which is not a problem for simple objects. However, comparing larger objects (or objects whose structure is unknown) is inconvenient because it requires a lot of boilerplate code.
So let’s see how shallow comparison of objects can help.
If you use shallow comparison to check objects, you must get the property list of both objects (usingObject.keys()
), and then check whether their attribute values are equal.
The following code is an implementation method of shallow comparison:
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; }
Inside the function,keys1
andkeys2
contain ## respectively. Array of #object1and
object2attribute names.
forto loop through the keys and compare each property of
object1and
object2.
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)Returns
true, because objects
hero1and
hero2have the same properties (
nameand
realName), and the values are also the same.
hero1and
hero3have different properties,
shallowEqual(hero1, hero3)will return
false.
const hero1 = { name: 'Batman', address: { city: 'Gotham' } }; const hero2 = { name: 'Batman', address: { city: 'Gotham' } }; shallowEqual(hero1, hero2); // => false
hero1and
hero2With the same content,
shallowEqual(hero1, hero2)will also return
false.
hero1.addressand
hero2.addressare different object instances. Therefore, shallow comparison considers
hero1.addressand
hero2.addressto be two different values.
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
更多编程相关知识,请访问:编程入门!!
The above is the detailed content of Several ways to compare objects in JavaScript. For more information, please follow other related articles on the PHP Chinese website!