检查对象相等性

执行深度比较来判断两个值是否相等。

  • 检查两个值是否完全相同。
  • 检查两个值是否都是具有相同时间的 Date 对象,使用 Date.prototype.getTime()
  • 检查两个非对象值是否具有相等的值(严格比较)。
  • 检查只有一个值是 nullundefined,或者它们的原型不同。
  • 如果以上条件都不满足,使用 Object.keys() 检查两个值是否具有相同数量的键。
  • 使用 Array.prototype.every() 检查 a 中的每个键是否存在于 b 中,并通过递归调用 equals() 来判断它们是否相等。
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]));
};

equals(
  { a: [2, { e: 3 }], b: [4], c: 'foo' },
  { a: [2, { e: 3 }], b: [4], c: 'foo' }
); // true
equals([1, 2, 3], { 0: 1, 1: 2, 2: 3 }); // true