如何比较 JavaScript 中的两个对象?
等值比较
即使两个不同的对象可以具有相同的属性和相等的值,但在使用松散或严格相等运算符(==或===)进行比较时,它们不被视为相等。这是因为 JavaScript 中的数组和对象是通过引用进行比较的。这与按值比较的原始值不同。
const a = { name: 'John', age: 26 };
const b = { name: 'John', age: 26 };
a === b; // false
SON.stringify
JSON.stringify()经常作为解决这个问题的方法出现。虽然它在某些情况下很有用,但比较序列化的字符串可能有其自身的缺陷。其中最常见的问题与导致相同序列化字符串的相似但不相等的值有关。
const equals = (a, b) => JSON.stringify(a) === JSON.stringify(b);
const a = { name: 'John', age: 26 };
const b = { name: 'John', age: 26 };
equals(a, b); // true
const c = { name: 'John' };
const d = { name: 'John', age: undefined };
equals(c, d); // true, should be false
深度相等比较
事实证明,比较两个对象并非易事。这就是浅层或深层相等比较辅助函数如此普遍的原因。这些通常使用递归来深入比较两个对象,占空值、特殊类型和嵌套等大多数场景。
const equals = (a, b) => {
if (a === b) return true;
if (a instanceof Date && b instanceof Date)
return a.getTime() === b.getTime();
if (!a || !b || (typeof a !== 'object' && typeof b !== 'object'))
return a === b;
if (a.prototype !== b.prototype) return false;
const keys = Object.keys(a);
if (keys.length !== Object.keys(b).length) return false;
return keys.every(k => equals(a[k], b[k]));
};
const a = { name: 'John', age: 26 };
const b = { name: 'John', age: 26 };
equals(a, b); // true
const c = { name: 'John' };
const d = { name: 'John', age: undefined };
equals(c, d); // false
上面的辅助函数处理了所有这些问题,我将会在后继文章 equals 详解中进行更深入的解释。