JavaScript对象比较的四种方法:引用、手动、浅层与深层

作者:半夏

时间:2026-10-25

浏览:190

本文详细解析JavaScript中比较对象的四种方式:引用比较、手动比较、浅层比较和深层比较。通过具体代码示例,阐述===、==、Object.is()及递归逻辑在对象相等性判断中的应用,帮助开发者根据对象结构选择最合适的比较策略。

文章目录

前言

在JavaScript中,对原始值进行比较十分直观,直接使用严格相等运算符(===)或宽松相等运算符(==)即可。


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

然而,由于对象包含结构化数据,其比较过程相对复杂。本文将介绍如何正确处理JavaScript中的对象比较。

引用比较

JavaScript提供了三种主要方法来比较值:

  • 严格相等运算符(===)
  • 宽松相等运算符(==)
  • Object.is()函数

使用上述任一方法比较对象时,仅当两个操作数引用同一个对象实例时,结果才为true。这种现象称为引用相等性(Reference Equality)。

下面通过定义两个对象hero1和hero2来演示引用相等性的实际表现。


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的结果为true,因为左右操作数指向同一个对象实例。

相反,hero1 === hero2的结果为false,因为hero1和hero2是两个不同的对象实例。

值得注意的是,尽管hero1和hero2的内容完全相同(都包含name属性且值为'Batman'),但hero1 === hero2仍返回false。

引用相等性适用于需要判断对象引用是否一致的场景。但在大多数情况下,我们需要比较的是对象的具体内容,即属性及其对应的值。

接下来,我们将探讨如何基于对象内容进行相等性比较。

手动比较

按内容比较对象最直接的方式是逐个读取属性并手动对比它们的值。

例如,我们可以编写一个名为isHeroEqual()的函数来比较两个hero对象。


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

该函数通过访问两个对象的name属性并比较其值来判断相等性。

对于属性数量较少的对象,编写如isHeroEqual()这样的专用比较函数是理想选择。这种方式性能良好,仅涉及少量的属性访问和相等性检查。

然而,手动比较需要提取每个属性,对于简单对象而言并非难题。但对于属性较多或结构未知的复杂对象,这种方法需要大量样板代码,显得不够便捷。

因此,我们可以尝试使用浅层比较来处理更复杂的情况。

浅层比较

执行浅层比较时,需获取两个对象的属性列表(使用Object.keys()),然后逐一检查属性值是否相等。

以下代码展示了浅层比较的一种实现方式。


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;
}

在函数内部,keys1和keys2分别存储object1和object2的属性名数组。

通过for循环遍历键,并对比object1和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)返回true,因为对象hero1和hero2拥有

相同的属性(name和realName),且对应的值也完全一致。

另一方面,由于hero1和hero3的属性不同,shallowEqual(hero1, hero3)将返回false。

但是,JavaScript中的对象支持嵌套结构。在此类情况下,浅层比较的效果有限。

下面演示对包含嵌套对象的对象执行浅层比较检查。


const hero1 = {
  name: 'Batman',
  address: {
    city: 'Gotham'
  }
};
const hero2 = {
  name: 'Batman',
  address: {
    city: 'Gotham'
  }
};

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

此时,尽管hero1和hero2的内容看似相同,shallowEqual(hero1, hero2)却返回false。

原因在于,嵌套对象hero1.address和hero2.address是不同的对象实例。因此,浅层比较将它们视为两个不同的值。

要解决嵌套对象的问题,必须进行深层比较。

深层比较

深层比较与浅层比较类似,区别在于:当属性值为对象时,会对嵌套对象执行递归的浅层比较。

以下是深层比较的具体实现代码。


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.js内置util模块的isDeepStrictEqual(object1, object2)或lodash库的_.isEqual(object1, object2)。

总结

引用相等性(使用===、==或Object.is())用于判断操作数是否指向同一个对象实例。

手动检查对象相等性需对属性值进行逐一比较。虽然需要手动编码,但由于逻辑简单,这种方法在特定场景下十分便捷。

当被比较的对象包含大量属性或在运行时确定对象结构时,使用浅层检查是更优的选择。

若比较的对象包含嵌套对象,则应当采用深层比较检查。

以上就是JavaScript对象四种比较方式的详细内容,更多关于JavaScript的资料请关注本站其它相关文章!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章