58

Seems like the following code should return a true, but it returns false.

var a = {};
var b = {};

console.log(a==b); //returns false
console.log(a===b); //returns false

How does this make sense?

Dennis
  • 32,200
  • 11
  • 64
  • 79
Maxx
  • 3,925
  • 8
  • 33
  • 38
  • 1
    possible duplicate of [In Javascript, why is \[1, 2\] == \[1, 2\] or ({a : 1}) == ({a : 1}) false?](http://stackoverflow.com/questions/7713794/in-javascript-why-is-1-2-1-2-or-a-1-a-1-false) also related: http://stackoverflow.com/questions/8699816/in-javascript-why-object – Felix Kling Jul 28 '12 at 22:30
  • Yea, it is pretty much the same question. – Maxx Jul 29 '12 at 03:04
  • 4
    You are trying to compare two objects. js objects returns true only when both point to the same memory location. So if you want to compare, whether the CONTENT of the objects are same. You have to first convert them to string like `JSON.stringify(a) == JSON.stringify(b)` – Saahithyan Vigneswaran Jul 26 '17 at 17:07

9 Answers9

62

The only difference between regular (==) and strict (===) equality is that the strict equality operator disables type conversion. Since you're already comparing two variables of the same type, the kind of equality operator you use doesn't matter.

Regardless of whether you use regular or strict equality, object comparisons only evaluate to true if you compare the same exact object.

That is, given var a = {}, b = a, c = {};, a == a, a == b, but a != c.

Two different objects (even if they both have zero or the same exact properties) will never compare equally. If you need to compare the equality of two object's properties, this question has very helpful answers.

Community
  • 1
  • 1
josh3736
  • 139,160
  • 33
  • 216
  • 263
15

How does this make sense?

Because "equality" of object references, in terms of the == and === operators, is purely based on whether the references refer to the same object. This is clearly laid out in the abstract equality comparison algorithm (used by ==) and the strict equality comparison algorithm (used by ===).

In your code, when you say a==b or a===b, you're not comparing the objects, you're comparing the references in a and b to see if they refer to the same object. This is just how JavaScript is defined, and in line with how equality operators in many (but not all) other languages are defined (Java, C# [unless the operator is overridden, as it is for string], and C++ for instance).

JavaScript has no inbuilt concept of equivalence, a comparison between objects that indicates whether they're equivalent (e.g., have the same properties with the same values, like Java's Object#equals). You can define one within your own codebase, but there's nothing intrinsic that defines it.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
6
use JSON.stringify(objname);

var a = {name : "name1"};
var b = {name : "name1"};

var c = JSON.stringify(a);
var d = JSON.stringify(b);

c==d;
//true
Sir. Hedgehog
  • 1,260
  • 3
  • 17
  • 40
Christina
  • 61
  • 1
  • 1
5

As from The Definitive Guide to Javascript.

Objects are not compared by value: two objects are not equal even if they have the same properties and values. This is true of arrays too: even if they have the same values in the same order.

var o = {x:1}, p = {x:1};  // Two objects with the same properties
o === p                    // => false: distinct objects are never equal 
var a = [], b = [];        // Two distinct, empty arrays 
a === b                    // => false: distinct arrays are never equal 

Objects are sometimes called reference types to distinguish them from JavaScript’s primitive types. Using this terminology, object values are references, and we say that objects are compared by reference: two object values are the same if and only if they refer to the same underlying object.

var a = {};   // The variable a refers to an empty object. 
var b = a;    // Now b refers to the same object. 
b.property = 1;     // Mutate the object referred to by variable b. 
a.property          // => 1: the change is also visible through variable a. 
a === b       // => true: a and b refer to the same object, so they are equal. 

If we want to compare two distinct objects we must compare their properties.

Charlie Lynch
  • 383
  • 3
  • 6
4

Here is a quick explanation of why {} === {} returns false in JavaScript:


From MDN Web Docs - Working with objects: Comparing objects.

In JavaScript, objects are a reference type. Two distinct objects are never equal, even if they have the same properties. Only comparing the same object reference with itself yields true.

// Two variables, two distinct objects with the same properties
var fruit = {name: 'apple'};
var fruitbear = {name: 'apple'};

fruit == fruitbear; // return false
fruit === fruitbear; // return false
// Two variables, a single object
var fruit = {name: 'apple'};
var fruitbear = fruit;  // Assign fruit object reference to fruitbear

// Here fruit and fruitbear are pointing to same object
fruit == fruitbear; // return true
fruit === fruitbear; // return true

fruit.name = 'grape';
console.log(fruitbear); // output: { name: "grape" }, instead of { name: "apple" }

For more information about comparison operators, see Comparison operators.

Marian13
  • 7,740
  • 2
  • 47
  • 51
2

How does this make sense?

Imagine these two objects:

var a = { someVar: 5 }
var b = { another: 'hi' }

Now if you did a === b, you would intuitively think it should be false (which is correct). But do you think it is false because the objects contain different keys, or because they are different objects? Next imagine removing the keys from each object:

delete a.someVar
delete b.another

Both are now empty objects, but the equality check will still be exactly the same, because you are still comparing whether or not a and b are the same object (not whether they contain the same keys and values).

Matt Way
  • 32,319
  • 10
  • 79
  • 85
1

===, the strictly equal operator for objects checks for identity.

Two objects are strictly equal if they refer to the same Object.

Those are two different objects, so they differ.

Think of two empty pages of paper. Their attributes are the same, yet they are not the same thing. If you write something on one of them, the other wouldn't change.

Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
-1

This is a workaround: Object.toJSON(obj1) == Object.toJSON(obj2)

By converting to string, comprasion will basically be in strings

josh3736
  • 139,160
  • 33
  • 216
  • 263
Anze Jarni
  • 1,141
  • 7
  • 7
  • The question was about the reason of the effect, an explanation of the observed, and not a “solution” to comparing two objects. – Kissaki Jul 28 '12 at 22:19
  • 1
    Given that the order of properties in a object is not guaranteed, this doesn't (always) work. You could end up with `{a:1,b:2} != {b:2,a:1}` even though they're the same. Additionally, objects with cyclic references don't translate to JSON. – josh3736 Jul 28 '12 at 22:19
  • First, this doesn't answer the question. Second, there is no `Object.toJSON` defined in JavaScript. Third, assuming you meant `JSON.stringify` from ES5, you can't rely on it returning exactly the same string for two objects that have the same properties with the same values, because nowhere in the spec does it require that the properties (which are *unordered*) be listed in the same order. The engine is free to do what it wants, which may vary depending on how the objects were constructed, even if they *end up* with the same properties with the same values. – T.J. Crowder Jul 28 '12 at 22:20
  • True, I have never thought of that because I always formulated objects with the same order of parameters. And yes, Kissaki, quite right, I just wanted to give an example how to solve it. – Anze Jarni Jul 28 '12 at 22:22
  • @AnzeJarni: *"...I always formulated objects with the same order of parameters..."* Assuming you meant properties, again, object properties *have no order*. Although granted, if you create an object and add `a`, `b`, and `c` properties to it; then create another object and add `a`, `b`, and `c` properties to it, it would be a very strange engine indeed that serialized those to JSON differently. But if you made the second object by adding `c`, `b`, and then `a` to it, that wouldn't necessarily be strange at all. – T.J. Crowder Jul 28 '12 at 22:22
  • To clarify, you obviously *write* an object's properties in an order in your source code -- `{a:1,b:2,c:3}`. However, the JS engine is free to physically *store* those properties in any order it wants. The order of JS object properties is an implementation detail, and can change between versions and engines; you cannot rely on it. `JSON.stringify` and loops (`for (k in obj)`) could very well go `c`,`b`, and then `a` when looping over my object, even though the source order is `a`,`b`,`c`. – josh3736 Jul 28 '12 at 22:29
  • Guys you have a point there. Is there any other way to check if two objects are equal without going looping and comparing parameters? – Anze Jarni Jul 28 '12 at 22:36
  • @AnzeJarni: Nothing built-in, no. You have to do a recursive-descent comparison disregarding order. – T.J. Crowder Jul 28 '12 at 22:37
  • Thanks and excuse my English. It is not my native language. – Anze Jarni Jul 28 '12 at 22:41
  • Be careful even then. It's very easy to mess up recursive-descent comparison. Even ignoring loops, consider stuff like this: `var demo = function(){_demo=1;return {A:5,B:function(){return _demo;}};}();` . – Brian Aug 26 '19 at 19:29
-1

In Javascript each object is unique hence {} == {} or {} === {} returns false. In other words Javascript compares objects by identity, not by value.

  1. Double equal to ( == ) Ex: '1' == 1 returns true because type is excluded

  2. Triple equal to ( === ) Ex: '1' === 1 returns false compares strictly, checks for type even

Marco
  • 7,007
  • 2
  • 19
  • 49
Sukshith S
  • 413
  • 6
  • 6