如何在 JavaScript 中比较对象

2023-05-27 0 178

在 JavaScript 中,第一类常常透过提及储存。 这意味著三个第一类才严苛等同于 另三个第一类。 多于当三个第一类都对准缓存中的同三个第一类时:

const o1 = { answer: 42 };const o2 = o1;const o3 = { answer: 42 };o1 === o2; // true, same referenceo1 === o3; // false, different reference but same keys and values

但,假如你想检查和三个POJO 与否有完全相同的统计数据咋办? 换言之,完全相同的键和值? 这儿有 3 种可能将的方式。

键和值浅成正比

一类单纯的方式是结点三个第一类中的每一键和值,并检查和键和值与否严苛成正比。

const o1 = { question: null, answer: 42 };const o2 = { question: null, answer: 42 };objectsEqual(o1, o2); // trueobjectsEqual(o1, { answer: 43 }); // falsefunction objectsEqual(o1, o2) { const entries1 = Object.entries(o1); const entries2 = Object.entries(o2); if (entries1.length !== entries2.length) { return false; } for (let i = 0; i < entries1.length; ++i) { // Keys if (entries1[i][0] !== entries2[i][0]) { return false; } // Values if (entries1[i][1] !== entries2[i][1]) { return false; } } return true;}

广度成正比采用 JSON.stringify()

上四节展现了怎样透过检查和三个第一类的键和值与否严苛成正比来较为第一类。 但,假如当中三个值是三个第一类呢?

const o1 = { name: { first: Arthur, lastName: Dent }, planet: Earth };const o2 = { name: { first: Arthur, lastName: Dent }, planet: Earth };objectsEqual(o1, o2); // false, because `o1.name !== o2.name`

你(们)能做到objectsEqual()递归,但你需要小心无限递归。 较为三个 POJO 与否广度成正比的一类单纯方式是较为它们的 JSON 表示,采用JSON.stringify():

const o1 = { name: { first: Arthur, lastName: Dent }, planet: Earth };const o2 = { name: { first: Arthur, lastName: Dent }, planet: Earth };JSON.stringify(o1) === JSON.stringify(o2); // truedelete o2.planet;JSON.stringify(o1) === JSON.stringify(o2); // false

JSON.stringify() 函数有一些限制,使其成为检查和广度成正比性的乏善可陈的选择。 首先,关键顺序很重要:

const o1 = { question: null, answer: 42 };const o2 = { answer: 42, question: null };JSON.stringify(o1) === JSON.stringify(o2); // false

其次,并非所有类型都可以用 JSON 表示。 JSON.stringify() 函数将日期转换为字符串,并忽略值为 undefined,这可能将会导致令人惊讶的结果。

const o1 = { myDate: new Date(2016-06-01), otherProperty: undefined };const o2 = { myDate: 2016-01-01T00:00:00.000Z };JSON.stringify(o1) === JSON.stringify(o2); // true

采用 Lodash 的 isEqual()

Lodash 的 isEqual()函数 是较为三个第一类的最复杂的方式。 它处理各种边缘情况,避免了前两种方式的许多缺陷。

const obj1 = { date: new Date(2020/06/01), num: new Number(1)};const obj2 = { date: new Date(2020/06/01), num: 1};_.isEqual(obj1, obj2); // true
const obj1 = { name: Will Riker, rank: Commander };class Character {}const obj2 = new Character();Object.assign(obj2, { name: Will Riker, rank: Commander });_.isEqual(obj1, obj2); // false

isEqual() 函数也足够聪明,可以避免无限递归。

const obj1 = {};const obj2 = {};obj1.circular = obj1;obj2.circular = obj1;_.isEqual(obj1, obj2); // true

假如您已经在采用 Lodash, isEqual() 是较为三个第一类与否广度成正比的最佳方式。 浅层严苛较为方式适用于您不担心嵌套第一类的情况,并且 JSON.stringify() 在您无法采用 Lodash 的情况下,可以帮助提供粗略的广度成正比性检查和。 但,假如你可以采用 Lodash, isEqual() 是检查和三个第一类与否广度成正比的最佳方式。

举报/反馈

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务