深比较的方法

41 阅读1分钟
function deepEquals (val1, val2) {
  // NaN 对比情况判断为相同
  if (Number.isNaN(val1) && Number.isNaN(val2)) return true;

  // 是否为对象
  let valIsObject = function (val) {
    return typeof val === 'object' && val !== null;
  }
  if (!valIsObject(val1) || !valIsObject(val2)) return val1 === val2;

  // 当val1和val2都为对象时,若地址相同则相等
  if (val1 === val2) return true;

  // 到这一步可以判断 val1 和 val2 都是对象,为了区分 {} 和 [],如果没有此判断,会导致 deepEquals({}, []) 返回 true
  let isEmptyObj = (Array.isArray(val1) && !Array.isArray(val2)) || (Array.isArray(val2) && !Array.isArray(val1));
  if (isEmptyObj) return false;
  
// 获取键的长度,长度不等则不同,也是为了下面遍历时以短的为基准
  if (Object.keys(val1).length !== Object.keys(val2).length) return false;
  for (let key in val1) {
    if (val1.hasOwnProperty(key)) {
      const isEqual = deepEquals(val1[key], val2[key])
      if (!isEqual)  return isEqual;
    }
  }
  return true;
}