Глубокое сравнение равных объектов в JavaScript

#javascript #function #object #recursion

Вопрос:

Я читаю красноречивый javascript, и мне дали задание написать глубокую равную функцию для объектов.

Мой код хорошо работает для объекта без вложенного объекта, но когда я передаю два объекта, в которых есть вложенный объект, мой код завершается ошибкой.

я попытался отладить его и заметил, что всякий раз, когда функция сталкивается с вложенным объектом, она не передает управление обратно основному объекту.

Возьмем, к примеру, у меня есть два объекта a и b ниже:

 let a = {
  name: "ade",
  last: "segun",
  dead: {
    name: "ade",
    last: "segun",
  },
  eaten: true,
};

let b = {
  name: "ade",
  last: "segun",
  dead: {
    name: "ade",
    last: "segun",
  },
  eaten: false,
};
 

После того, как функция проверяет наличие мертвого свойства, которое является вложенным объектом, она не возвращается к основному объекту и проверяет наличие eaten свойства.

Что я сделал не так? Это Мой код

 let a = { name: "ade", last: "segun", dead: { name: "ade", last: "segun", }, eaten: true, }; 
let b = { name: "ade", last: "segun", dead: { name: "ade", last: "segun", }, eaten: false, };


const deepEqual = (obj1, obj2) => {
  const keysA = Object.keys(obj1);
  const keysB = Object.keys(obj2);
  if (keysA.length !== keysB.length) {
    return false;
  }
  let c;
  for (let key of keysA) {
    // c checks whether the key is part of keysB array
    c = keysB[keysB.indexOf(key)];
    if (key !== c) {
      return false;
    }
    if (
      typeof obj1[key] === "object" amp;amp;
      typeof obj2[c] === "object" amp;amp;
      obj1[key] !== null amp;amp;
      obj2[c] !== null
    ) {
      return deepEqual(obj1[key], obj2[c]);
    } else {
      if (obj1[key] !== obj2[c]) return false;
    }
  }
  return true;
};

console.log(deepEqual(a, b)); //true 

Ответ №1:

Эта строка в вашем коде…

 return deepEqual(obj1[key], obj2[c]);
 

… в основном функция сравнения останавливается при обнаружении первого вложенного объекта. Вместо этого должно произойти следующее: 1) вычисляется результат deepEqual, и 2) только если это так false , функция немедленно возвращает его. Например:

 const isDeeplyEqual = deepEqual(obj1[key], obj2[c]);
if (!isDeeplyEqual) return false;
 

… или просто:

 if (!deepEqual(obj1[key], obj2[c])) return false;