js判斷兩個對象是否完全相等

deepEqual中傳入第一個對象和第二個對象,返回值為true為完全相等,false為不相等

/**
 * 用來判斷一個對象是否是某種類型的靜態(tài)類
 */
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";
  }
};

/**
 * 對象的深度相等比較,不考慮指針,只比較值
 * 需要特別注意的是,比較之前已經(jīng)對數(shù)據(jù)進(jìn)行了深度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;
    }
  }
}

/**
 * 對對象進(jìn)行深層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;
    }
  }
}

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容