3

Questions about deep comparison of objects have been asked, and I have the solution. But there is a line in the solution that I don't completely understand.

This is the solution, it is a question in Ch 4 of Eloquent JS to compare objects. I get all of it except the line:

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

It is found toward the bottom. Here is full function:

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;
}

Is if (!(prop in a) comparing the existence of a property in 'b' at that index, or is it comparing values?

Really the same q. about the second half, but I know it's a different answer: what type of comparison is !deepEqual(a[prop], b[prop]) making (e.g., true or false)? I understand the recursion, but as in my previous question, is this making an 'it exists' comparison, or a comparison of the information in the values?

Thank you in advance.

Frank Tan
  • 4,234
  • 2
  • 19
  • 29
hikinthru
  • 49
  • 7

3 Answers3

1

According to MDN:

The in operator returns true if the specified property is in the specified object.

Also:

The for...in statement iterates over the enumerable properties of an object, in arbitrary order. For each distinct property, statements can be executed.

So to answer your first question, prop in a is checking whether prop, a field from object b, exists in object a.

To answer your second question, deepEqual(a[prop], b[prop]) is checking whether the object a[prop] and b[prop] are equal including all its children and contents.

0xcaff
  • 13,085
  • 5
  • 47
  • 55
  • Thank you caffinatedmonky, (and everyone else for the assistance). That's what I thought but wanted to confirm. I appreciate the information on "in". – hikinthru Apr 22 '16 at 02:40
  • @hikinthru Welcome to stackoverflow. Thank's for not making your first post a syntax error. – 0xcaff Apr 22 '16 at 02:42
0

The in operator returns true if the object on the right of the expression contains a key with the value of the string on the left of the expression.

Eg: prop in a is true if a contains a key with the same name as the string value of prop. Eg:

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

If prop was set to "record" then deepEqual(a[prop], b[prop]) recursively compares the values in a.record and b.record.

Alex McMillan
  • 17,096
  • 12
  • 55
  • 88
0

It's checking for existence. It says: "For each property in B, examine A. If A doesn't have the property, or if the value of the property on A doesn't deeply equal the value of the property on B, return false".

An alternate implementation would avoid the existence check on that line, and instead use if (typeof A == 'undefined') at the top of the function to validate the input parameters at the beginning of each round of recursion...at a glance, I think that'd be equivalent, but less efficient. The current implementation avoids the invocation on the undefined property.

S McCrohan
  • 6,663
  • 1
  • 30
  • 39
  • But then, would `a = {x:undefined}` and `b = {y:undefined}` be "deeply equal" or not? – Bergi Apr 22 '16 at 02:39
  • Good question! Apparently `undefined == undefined` is true (I wasn't sure it would be...could have been treated as indeterminate), so I suppose a and b in your question SHOULD be deeply equal. Nice catch. – S McCrohan Apr 22 '16 at 02:49