发布于 2026-01-06 4 阅读
0

Deep Equality checking of Objects in Vanilla JavaScript 👨‍👦 DEV's Worldwide Show and Tell Challenge Presented by Mux: Pitch Your Projects!

在原生 JavaScript 中对对象进行深度相等性检查👨‍👦

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

你是否曾经遇到过需要用 JavaScript 比较两个对象的情况?或许你发现 JavaScript 本身并没有提供解决这个问题的原生解决方案。在本教程中,我们将构建自己的实现方案!

你将了解到以下内容:

  • 按值传递与按引用传递
  • Object.keys() 方法
  • 创建递归函数

你可以使用 Lodash 库,并使用其.isEqual方法对两个对象进行深度质量检查,但为了练习原生 JavaScript,最好自己创建解决方案。

假设我们有以下对象:

const obj1 = { name: 'Peter', stats: { points: 45, isActive: false }};
const obj2 = { name: 'Peter', stats: { points: 45, isActive: false }};

console.log(obj1 === obj2) // returns false

这两个对象完全相同,但 JavaScript 仍然返回 false。为什么?

这是因为在 JavaScript 中,像字符串和数字这样的基本类型是按其值进行比较的,而对象则是按引用进行比较的

JavaScript 会将你创建的每个对象分配到内存中的不同位置。因此,即使你的对象内容完全相同,它们的引用(内存中的位置)也不同!

视觉的

让我们开始创建函数。我们将创建一个名为 `function` 的函数compareObjects,它接受两个参数。首先,我们将检查这两个参数的类型是否相同,以及它们的值是否相同。

const compareObjects = (a, b) => a === b ? true : false;

const obj1 = { name: 'Peter', stats: { points: 45, isActive: false }};

compareObjects(obj1, obj1) // returns true

接下来,我们将添加检查,确认这两个参数的类型是否正确object,以及它们是否不是null值。为了避免类型转换,我们将使用 ` :` 而!=不是!==`:`。

const compareObjects = (a, b) => {
 if (a === b) return true;

 if (typeof a != 'object' || typeof b != 'object' || typeof a == null || typeof b == null) return false;
}

然后我们将检查两个对象的对象键的长度。如果它们的长度不同,我们就可以确定这两个对象不是同一个对象。

...
let keysA = Object.keys(a), keysB = Object.keys(b);
 if (keysA.length != keysB.length) return false;
...

接下来,我们将使用循环遍历 keysA 数组的键for of。循环for of适用于数组,也for in适用于对象。

在这个循环中,我们将检查每个键是否存在于 keysB 数组中。此外,我们将比较每个键的值,并将这些值传递回我们的compareObjects函数,从而使我们的函数递归(调用自身)。

一旦我们的键值对中有一个不一致,循环和函数就会停止,并返回 false。

...
for (let key of keysA) {
    if (!keysB.includes(key) || !compareObjects(a[key], b[key])) return false;
}
...

我们还要检查这两种方法是否相同,为此,我们将把函数转换为字符串,然后比较这两个值:

...
if (typeof a[key] === 'function' || typeof b[key] === 'function') {
   if (a[key].toString() != b[key].toString()) return false;
}
...

如果循环检查了每个键并将每个嵌套值传递回它自己的函数,并且没有返回 false,那么只剩下一件事要做:返回 true!

完整功能:

const compareObjects = (a, b) => {
 if (a === b) return true;

 if (typeof a != 'object' || typeof b != 'object' || a == null || b == null) return false;

 let keysA = Object.keys(a), keysB = Object.keys(b);

 if (keysA.length != keysB.length) return false;

 for (let key of keysA) {
   if (!keysB.includes(key)) return false;

   if (typeof a[key] === 'function' || typeof b[key] === 'function') {
     if (a[key].toString() != b[key].toString()) return false;
   } else {
     if (!compareObjects(a[key], b[key])) return false;
   }
 }

 return true;
}

感谢观看本教程,记得关注我获取更多内容哦!🧠

更多参考信息,请参阅《Eloquent JavaScript》一书。

文章来源:https://dev.to/sanderdebr/deep-equality-checking-of-objects-in-vanilla-javascript-5592