3

I was looking at the JavaScript console in Chrome and noticed something strange, even though they appear the same, obj and JSON.parse(JSON.stringify(obj)) are not the same. Why is that?

var obj = {test:'this is a test', another: {omg:'ay dios mio', check:true}};
console.log(obj, JSON.parse(JSON.stringify(obj)));
console.log(obj == JSON.parse(JSON.stringify(obj)));

They look identical but return false when you check equality. Why is that?

Spedwards
  • 4,167
  • 16
  • 49
  • 106
  • 1
    Not *really* a duplicate, but the answer there answers your question too. – Lix Jul 20 '14 at 11:37
  • 1
    If you convert both to strings `JSON.stringify()` then you'll see their values are equal. – Lix Jul 20 '14 at 11:38
  • 3
    [MDN: Equality operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality_operators) `[...]If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.` – t.niese Jul 20 '14 at 11:39

3 Answers3

9

They're not equal for the same reason this returns false:

({omg:'ay dios mio', check:true}) == ({omg:'ay dios mio', check:true})

You're not comparing the values inside the object, but the object references. They'll be different.

Overv
  • 8,433
  • 2
  • 40
  • 70
5

The objects are testing for REFERENCES.

While primitives are testing for VALUE.

Dávid Szabó
  • 2,235
  • 2
  • 14
  • 26
5

Because the obj does not reference the parsed object in memory. So these are 2 different declarations. If you do this:

var a = [ 10 ],
    b = [ 10 ];

Then there are 2 instances of arrays with the same values, but that doesn't make them the same array. So a != b, even though 10 == 10. You can increase the value of a[0] to 15, but that doesn't change the value of b[0] to 15.

Therefore, if you want to compare objects, you have to loop through them and check if the values of the objects are the same.

A function to compare (borrowed from jQuery object equality )

$.fn.equals = function(compareTo) {
  if (!compareTo || this.length != compareTo.length) {
    return false;
  }
  for (var i = 0; i < this.length; ++i) {
    if (this[i] !== compareTo[i]) {
      return false;
    }
  }
  return true;
};
Community
  • 1
  • 1
Niels
  • 48,601
  • 4
  • 62
  • 81
  • But the way they reference are the same, I could have made it objects with just 1 property. That's true. – Niels Jul 20 '14 at 11:40
  • Yes (because arrays are objects). It's just, introducing further non-relevant factors tends to obscure the explanation... – T.J. Crowder Jul 20 '14 at 11:41