0

The deepEqual function is supposed to take in 2 values in see if they are exactly the same. The results for the first and second test come back as expected. Is there perhaps something wrong with the way I'm incorporating the recursive call?

function deepEqual(obj1, obj2) {
  if (typeof obj1 == 'object' && typeof obj1 !== null && typeof obj2 == 'object' && typeof obj2 !== null) {
    if (obj1.length != obj2.length) {return false;}
    for (var prop in obj1) {
      if (typeof obj1[prop] == 'object') {deepEqual(obj1[prop], obj2[prop]);}
      if (obj1[prop] != obj2[prop]) {return false;}
    }
    return true;
  } else if (obj1 === obj2) {return true;}
  else {return false;}
}

var obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
// → true -> true
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false -> false
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
// → true -> false
3
  • 2
    @SPlatten It doesn't work for objects. It just tests for reference equality. Commented Jul 18, 2016 at 14:04
  • @SPlatten: The OP is clearly trying to test for equivalence, not identity. Commented Jul 18, 2016 at 14:05
  • 1
    You should test for the existance of 'prop' in obj2 before passing it onto deepEqual. Commented Jul 18, 2016 at 14:06

1 Answer 1

6

Is there perhaps something wrong with the way I'm incorporating the recursive call?

Yes, you're throwing away its return value. You should be checking its return value and, if it's false, returning false early.

if (typeof obj1[prop] == 'object') {
    if (!deepEqual(obj1[prop], obj2[prop])) {
        return false;
    }
}

Side note: There are several other issues in that code. I'm not going to get into a full review of it, but for instance, the if following the line above testing obj1[prop] to see if it's an object really should be else if, e.g.:

if (typeof obj1[prop] == 'object') {
    if (!deepEqual(obj1[prop], obj2[prop])) {
        return false;
    }
} else if (obj1[prop] != obj2[prop]) {
//^^^^------------------------------------------ here
    return false;
}
Sign up to request clarification or add additional context in comments.

5 Comments

Unbelievable how fast you were on this :) Nice!
@T.J.Crowder So the original code wouldn't be able to return anything from that if statement. However, wouldn't the function still be able to finish the for loop and eventually return true? I was also under the impression that successive if statements were just run in order. Was it just repetitive in this case?
@James: The issue with the missing else is that if obj1[prop] and obj2[prop] are objects and they're not the same object, after doing the deepEquals call, you'll move on to the if (obj1[prop] != obj2[prop]) check, which would be true (because they're different objects) and you'd return false.
@T.J.Crowder I'm slightly confused. If the two objects after doing deepEquals are not the same, isn't it correct for the program to return false?
@James: I'm assuming the goal of deepEquals is to check for equivalence. E.g., var a = {foo:"bar"}; var b = {foo:"bar"}; console.log(deepEquals(a, b)); // true That's not what == and === with object references check; they check for identity (are the references both to the same object), not for equivalence (are the two different objects equivalent to each other, e.g., do they have the same properties with the same values).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.