js判断两个对象是否完全相等

deepEqual中传入第一个对象和第二个对象,返回值为true为完全相等,false为不相等

/**
 * 用来判断一个对象是否是某种类型的静态类
 */
export const ObjType = {
  isObject(obj) {
    return getObjType(obj) === "Object";
  },
  isArray(obj) {
    return getObjType(obj) === "Array";
  },
  isString(obj) {
    return getObjType(obj) === "String";
  },
  isNumber(obj) {
    return getObjType(obj) === "Number";
  },
  isBoolean(obj) {
    return getObjType(obj) === "Boolean";
  },
  isSymbol(obj) {
    return getObjType(obj) === "Symbol";
  },
  isFunction(obj) {
    return getObjType(obj) === "Function";
  },
  isNull(obj) {
    return getObjType(obj) === "Null";
  },
  isUndefined(obj) {
    return getObjType(obj) === "Undefined";
  },
  isFormData(obj) {
    return getObjType(obj) === "FormData";
  },
  isFile(obj) {
    return getObjType(obj) === "File";
  }
};

/**
 * 对象的深度相等比较,不考虑指针,只比较值
 * 需要特别注意的是,比较之前已经对数据进行了深度trim处理
 * @param {*} obj 第一个对象
 * @param {*} obj2 第二个对象
 */
export function deepEqual(obj, obj2) {
  obj = deepTrim(obj);
  obj2 = deepTrim(obj2);
  return _deepEqual(obj, obj2);
  function _deepEqual(obj, obj2) {
    if (getObjType(obj) !== getObjType(obj2)) {
      return false;
    }
    if (ObjType.isObject(obj)) {
      const keys1 = Object.keys(obj);
      const keys2 = Object.keys(obj2);
      if (keys1.length !== keys2.length) {
        return false;
      }
      return keys1.every(key => {
        return _deepEqual(obj[key], obj2[key]);
      });
    } else if (ObjType.isArray(obj)) {
      if (obj.length !== obj2.length) {
        return false;
      }
      return obj.every((item, i) => {
        return _deepEqual(obj[i], obj2[i]);
      });
    } else if (ObjType.isFormData(obj)) {
      const arr1 = [...obj];
      const arr2 = [...obj2];
      if (arr1.length !== arr2.length) {
        return false;
      }
      return arr1.every((kv, idx) => {
        const [k1, v1] = arr1[idx];
        const [k2, v2] = arr2[idx];
        if (k1 !== k2) {
          return false;
        }
        if (getObjType(v1) !== getObjType(v2)) {
          return false;
        }
        if (ObjType.isFile(v1)) {
          const keys = ["name", "size", "type"];
          return keys.every(key => {
            return v1[key] === v2[key];
          });
        } else {
          return v1 === v2;
        }
      });
    } else {
      return obj === obj2;
    }
  }
}

/**
 * 对对象进行深层trim
 */
export function deepTrim(data) {
  return _deepTrim(data);
  function _deepTrim(data) {
    if (ObjType.isFormData(data)) {
      const formData = new FormData();
      const iterator = data.entries();
      const items = [];
      // eslint-disable-next-line no-constant-condition
      while (true) {
        const { value, done } = iterator.next();
        if (done) {
          break;
        }
        const name = value[0];
        let val = value[1];
        if (ObjType.isString(val)) {
          val = val.trim();
        }
        items.push([name, val]);
      }
      items.forEach(item => {
        const [name, val] = item;
        formData.append(name, val);
      });
      return formData;
    } else if (ObjType.isObject(data) || ObjType.isArray(data)) {
      const obj = ObjType.isObject(data) ? {} : [];
      for (const i in data) {
        obj[i] = _deepTrim(data[i]);
      }
      return obj;
    } else if (ObjType.isString(data)) {
      return data.trim();
    } else {
      return data;
    }
  }
}

/**
 * 获取元素类型,比如数组是Array,对象是Object,字符串是String
 * @param {*} obj
 * @returns {string}
 */
export function getObjType(obj) {
  const typeStr = Object.prototype.toString.call(obj);
  return typeStr.replace(/\[object (\w+)\]/, "$1");
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容