Javascript глубокое сравнение

Были заданы вопросы о глубоком сравнении объектов, и у меня есть решение. Но в решении есть черта, которую я не совсем понимаю.

Это решение, это вопрос в главе 4 Eloquent JS для сравнения объектов. Я получаю все это, кроме строки:

    if (!(prop in a) || !deepEqual(a[prop], b[prop]))

Это найдено к основанию. Вот полная функция:

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

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

  var propsInA = 0, propsInB = 0;

  for (var prop in a)
    propsInA += 1;

  for (var prop in b) {
    propsInB += 1;
    if (!(prop in a) || !deepEqual(a[prop], b[prop]))
      return false;
  }

  return propsInA == propsInB;
}

Является if (!(prop in a) сравнивая существование свойства в 'b' по этому индексу, или сравнивает значения?

Действительно тот же вопрос. о второй половине, но я знаю, что это другой ответ: какой тип сравнения !deepEqual(a[prop], b[prop]) делая (например, правда или ложь)? Я понимаю рекурсию, но, как и в моем предыдущем вопросе, это делает сравнение "существует" или сравнение информации в значениях?

Заранее спасибо.

3 ответа

Решение

Согласно MDN:

Оператор in возвращает true если указанное свойство находится в указанном объекте.

Также:

Оператор for... in перебирает перечисляемые свойства объекта в произвольном порядке. Для каждого отдельного свойства могут быть выполнены операторы.

Итак, чтобы ответить на ваш первый вопрос, prop in a проверяет, prop, поле из объекта bсуществует в объекте a,

Чтобы ответить на ваш второй вопрос, deepEqual(a[prop], b[prop]) проверяет, является ли объект a[prop] а также b[prop] равны в том числе всех его детей и содержания.

in Оператор возвращает true, если объект справа от выражения содержит ключ со значением строки слева от выражения.

Например: prop in a верно, если a содержит ключ с тем же именем, что и строковое значение prop, Например:

var prop = "age";

var obj1 = {
    name: "Dave",
    age: 21,
    record: { ... }
};
var obj2 = {
    name: "John",
    record: { ... }
};

console.log(prop in obj1); // true
console.log(prop in obj2); // false

Если prop был установлен на "record" затем deepEqual(a[prop], b[prop]) рекурсивно сравнивает значения в a.record а также b.record,

Это проверка на существование. В нем говорится: "Для каждого свойства в B проверьте A. Если A не обладает свойством или если значение свойства на A не глубоко равно значению свойства на B, верните false".

Альтернативная реализация позволит избежать проверки существования в этой строке и вместо этого использовать if (typeof A == 'undefined') вверху функции для проверки входных параметров в начале каждого раунда рекурсии... на первый взгляд, я думаю, что это будет эквивалентно, но менее эффективно. Текущая реализация избегает вызова неопределенного свойства.

Другие вопросы по тегам