Не работает один из созданных методов создания объектов

Есть два функции, первая работающая, вторая нет, как можно исправить вторую, чтобы с помощью двойных циклов был тот же результат?

Первая:

function deepEqual1(a, b) {
  if (a === b) return true;
  
  if (a == null || typeof a != "object" ||
      b == null || typeof b != "object") return false;

  let keysA = Object.keys(a), keysB = Object.keys(b);

  if (keysA.length != keysB.length) return false;

  for (let key of keysA) {
    if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
  }

  return true;
}

Вторая:

function deepEqual2(obj1, obj2) {
    if (typeof(obj1) === typeof(obj2) === 'object' !== null) {
        for (let i in obj1) {
            for (let c in obj2) {
                let len = Object.keys(obj1);
                if (obj1[i] == obj2[c]) {
                    //console.log(obj1[i])
                    console.log(i)
                }
            }
        }
    }
}

let obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
// → true

Ответы (1 шт):

Автор решения: OPTIMUS PRIME

Бросилось в глаза (интерпретируется слева направо, не работает как ожидалось):

► typeof(obj1) === typeof(obj2) === 'object' !== null
//typeof(obj1) === typeof(obj2) → true

► true === 'object' !== null
//true === 'object' → false

► false !== null
true

По функции: Рекурсия сама вместо вас в процессе хранит необходимые данные. Если хочется делать это без рекурсии, придется во время цикла «руками» их где-то хранить и вытаскивать.

let obj = { here: { is: "an" }, object: 2 };

console.log(deepEqual(obj, obj)); // true
console.log(deepEqual(obj, { here: 1, object: 2 })); // false
console.log(deepEqual(obj, { here: { is: "an" }, object: 2 })); // true
console.log(deepEqual({a:{b:{c:{d:{e:{f:1}}}}}}, {a:{b:{c:{d:{e:{f:1}}}}}})); // true

function deepEqual(a, b) {
  if (a === b) return true;

  if (a == null || typeof a != "object" ||
      b == null || typeof b != "object") return false;

  /***/
  // Сначала будет перебирать все ключи начального объекта.
  // Если будет натыкаться на вложенные объекты - добавит их в очередь проверок.
  let queue = [];
  
  // Когда перебор первого уровня завершен - заглянет в очередь,
  // и повторит итерацию дла вложенных в неё объектов.

  let keys_a = Object.keys(a).sort(), keys_b = Object.keys(b).sort();
  if (keys_a.length != keys_b.length) return false;
  
  let curr_a = a, curr_b = b;

  let i = 0;
  while (true) {
    let key_a = keys_a[i], key_b = keys_b[i];
    i++;

    if (key_a !== key_b) return false;

    let val_a = curr_a[key_a], val_b = curr_b[key_b];

    if (val_a !== val_b) {

      if (val_a !== null && typeof val_a == "object" &&
          val_b !== null && typeof val_b == "object") {

        queue.push([val_a, val_b]); // Объекты идут парами, в массиве.
        continue;

      } else {
        // Значения не равны, и это не объекты.
        return false;
        
      }

    }

    /***/
    if (i >= keys_a.length) {
      // Перебор всех ключей объекта завершен.

      if (queue.length == 0) {
        // В очереди больше нет объектов - значит все оказались равны.
        return true;

      } else {

        // Обновляет счетчик и "текущие" ключи для будущих итераций.
        i = 0;
        [curr_a, curr_b] = queue.pop();
        keys_a = Object.keys(curr_a).sort(), keys_b = Object.keys(curr_b).sort();        
        if (keys_a.length != keys_b.length) return false;

      }

    }

  } // End while

}

val_a !== null && typeof val_a == "object" — Проверка на null нужна, чтобы условие точно оставляло только объекты.

console.log( typeof null ); // "object"

→ Ссылка