Home  >  Article  >  Web Front-end  >  Several ways to compare objects in JavaScript

Several ways to compare objects in JavaScript

青灯夜游
青灯夜游forward
2020-12-24 17:59:133150browse

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.

Several ways to compare objects in JavaScript

#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.

1. Reference comparison

JavaScript provides 3 methods for comparing values:

  • Strict equality operator ===
  • Loose equality operator==
  • Object.is() Function

When comparing objects using any of the above methods, the comparison evaluates to true only if the compared values ​​refer to the same object instance. This is reference equality.

Let's define objects hero1 and hero2 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 to true because both operands point to the same object instance hero1.

On the other hand, hero1 === hero2 evaluates to false because hero1 and hero2 are Different object instances.

Interestingly, the contents of the hero1 and hero2 objects are the same: both objects have a name attribute, and its other The value is 'Batman'. Still, even when comparing objects of the same structure, hero1 === hero2 results in false.

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.

2. Manual comparison

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 function isHeroEqual() 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 properties name and compare their values.

If the object being compared has some properties, I prefer to write a comparison function like isHeroEqual(). 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.

3. Shallow comparison

If you use shallow comparison to check objects, you must get the property list of both objects (using Object.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 and keys2 contain ## respectively. Array of #object1 and object2 attribute names.

Use

for to loop through the keys and compare each property of object1 and object2.

Using shallow comparison, you can easily check equality on objects with many properties:

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) Returns true, because objects hero1 and hero2 have the same properties (name and realName), and the values ​​are also the same.

On the other hand, since

hero1 and hero3 have different properties, shallowEqual(hero1, hero3) will return false.

But objects in JavaScript can be nested. Shallow comparisons don't work well in this case.

The following performs a shallow comparison check on objects with nested objects:

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

This time, even with two objects

hero1 and hero2 With the same content, shallowEqual(hero1, hero2) will also return false.

This happens because the nested objects

hero1.address and hero2.address are different object instances. Therefore, shallow comparison considers hero1.address and hero2.address to be two different values.

Solving the problem of nested objects requires deep comparison.

4. Deep comparison

Deep comparison is similar to shallow comparison, except that when an object is contained in a property, a recursive shallow comparison will be performed on the nested object. layer comparison.

Look at the implementation of deep comparison:

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

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

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!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete