10

I was checking this question Javascript Deep Comparison The solution of the question asker did not convince me so I tried to analyze the problem and came up with that

var obj = {here: 2}; console.log(deepEqual(obj, obj)); // → true console.log(deepEqual(obj, {here: 1})); // → false console.log(deepEqual(obj, {here: 2})); // → true function deepEqual(a,b) { if( (typeof a == 'object' && a != null) && (typeof b == 'object' && b != null) ) { var count = [0,0]; for( var key in a) count[0]++; for( var key in b) count[1]++; if( count[0]-count[1] != 0) {console.log('1');return false;} for( var key in a) { if(!(key in b) || !deepEqual(a[key],b[key])) {console.log('2');return false;} } for( var key in b) { if(!(key in a) || !deepEqual(b[key],a[key])) {console.log('3');return false;} } } console.log('a:'+a+' b:'+b); return a===b; } obj === { here:2 } 

This code fails the last test ( console.log(deepEqual(obj, {here: 2})) ) but the logic of considering objects deeply equal if they have respectively equal keys and values despite being different instances in memory does not convince me. Is there's a problem with my 'solution' or the mistake lies in the presumptions of the exercise? Is the code mentioned in the question I linked valid?

Resources that hikinthru forgot to mention ( http://eloquentjavascript.net/04_data.html#exercise_deep_compare )

4
  • It's unclear what you're asking. Are you saying that you disagree with what deep equality should mean? Commented Jul 15, 2016 at 17:18
  • That's part of what I am asking. Is my advocated solution wrong or there is a problem with the question? The last line shows that for browsers even objects with same keys and their respective values are not strictly equal. Please if there's a problem with the question let me know and I'll delete it. Commented Jul 15, 2016 at 23:18
  • Well your function never does return true after having established that both objects have the same properties… Commented Jul 20, 2016 at 16:53
  • A possible solution can be found here: link Commented Jan 16, 2024 at 10:29

1 Answer 1

19

"Deep equality", which is what the question you linked to is talking about, and "strict equality" are two different things. "Deep equality" means, as you said, "equal keys and equal values." "Strict equality" for objects means "same instance." Strict equality implies deep equality, but objects can be deeply equal without being strictly equal.

Your code is somewhat inefficient because you only need one loop, but it will behave correctly if you check a === b in an else block and return true after the for loops. This is because you should be handling objects separately from primitive values like strings and numbers. I've removed some logging for the sake of clarity, and I tried to keep your style.

var obj = {here: 2}; console.log(deepEqual(obj, obj)); // → true console.log(deepEqual(obj, {here: 1})); // → false console.log(deepEqual(obj, {here: 2})); // → true console.log(obj === { here:2 }); // → false function deepEqual(a,b) { if( (typeof a == 'object' && a != null) && (typeof b == 'object' && b != null) ) { var count = [0,0]; for( var key in a) count[0]++; for( var key in b) count[1]++; if( count[0]-count[1] != 0) {return false;} for( var key in a) { if(!(key in b) || !deepEqual(a[key],b[key])) {return false;} } for( var key in b) { if(!(key in a) || !deepEqual(b[key],a[key])) {return false;} } return true; } else { return a === b; } }

Sign up to request clarification or add additional context in comments.

2 Comments

May be with a max depth indicator, it would be better. Thanks.
a === b should really be Object.is(a, b).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.