Why when comparing 2 objects (===) returns false .

But with other operations ( >, <, +, -, *, / ) 2 objects - gives the desired result (that is, the valueOf methods work)

let man = { name: 'Sergey', surname: 'Sergeev', age: 30, valueOf(){ return this.age; } } let man2 = { name: 'Ivan', surname: 'Ivanov', age: 30, valueOf(){ return this.age; } } console.log(man === man2) 

Reported as a duplicate at Grundy. javascript Aug 2 '17 at 6:14 .

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

  • Objects can not be compared. - Nazar Kalytiuk
  • what exactly do you want to do? - Mikhail Vaysman
  • @NazarKalituk, you can - Grundy
  • The question can not be a duplicate. The context of the questions is different. Especially the first link. That is, I’ll get it now, if there are questions related to the conversion to JS - to send everyone to these links (where it’s about the specification) without giving a specific answer? - Alexander Bragin
  • Moreover, a person has a crucial point: in comparison, he uses the valueOf method, albeit implicitly in his code, at that time I would recommend using the properties of man.age and man2.age objects for this man2.age ... - Alexander Bragin

3 answers 3

If you want to compare age (and generally do any operations with the value of properties) - make it easier:

 let man = { name: 'Sergey', surname: 'Sergeev', age: 30, valueOf() { return this.age; } } let man2 = { name: 'Ivan', surname: 'Ivanov', age: 30, valueOf() { return this.age; } } console.log(man.age === man2.age); 

Below is an explanation

The valueOf () method returns the primitive value of the specified object.

JavaScript calls the valueOf method to convert an object to a primitive value. You rarely need to call the valueOf method yourself; JavaScript automatically calls it when an object is detected, when a primitive value is expected .

The fact is that when you perform primitive operations >, <, +, -, *, / with objects, the initial value of each object is returned for each object at that moment - in your case, what you have redefined in the valueOf methods. And operations are already extinguished with the returned values.

When you perform operations ==, === on objects, object references are compared.

But if you do this: when one of the operands has a primitive value, then the object will also be transformed into a primitive (when there is no strict altitude):

 let man = { name: 'Sergey', surname: 'Sergeev', age: 30, valueOf() { return this.age; } } let man2 = { name: 'Ivan', surname: 'Ivanov', age: 30, valueOf() { return this.age; } } console.log(man === 30); // false, потому что сравниваются ссылки на объекты (=== — строгое сравнение) console.log(man == 30); // true, потому что для man вернется примитивное значение 

Two “identical” even empty objects will never be equal, because objects will always compare links

 console.log({} == {}); console.log({} === {}); 

But if the variables pointing to the same object are compared (they have the same reference), then true will be returned

 var obj1 = {}; obj1.foo = 100; var obj2 = obj1; obj2.biz = 200; obj1.bar = { text: 'bar' }; console.log(obj1 == obj2); console.log(obj1 === obj2); 

Additional information on type conversion for primitives and object conversion:

  • The whole point is that the operation == and === is not an arithmetic operation, so valueOf does not work. But if == comes with a primitive, then the object begins to be reduced to a primitive too. at the same time otrabatyvet valueOf - I correctly understood? - ruslik
  • @ruslik To make it easier to understand when an object is called valueOf - quoting MDN JavaScript automatically calls it ( valueOf ) when it detects an object, when a primitive value is expected. For example, 10 + obj . Arithmetic operation? Yes. Therefore, the object must be "converted" to the initial value - the valueOf method is called. But if valueOf returns true ? That will be another transformation: true will be 1 and the result will be 11. At the end of the answer I added additional links - Ilya Kantor in his blog wrote everything perfectly with examples :) - Alexander Bragin
  • @ruslik has excellent documentation from MDN for JS and more. For example, valueOf () . They are now positioning themselves (will be) as documentation for developers. I have not had to look into the specification yet - it’s still more for browser developers. First of all, I look at the information on MDN , then on here or his English. option (improved). - Alexander Bragin
  • @ruslik it is important to understand the principles in order to understand how a program behaves in any situation. There are also nuances with browsers, but this is another story (not by valueOf, but generally by parsing, interpreting and executing JS in browser engines) ... - Alexander Bragin
  • Why then [] == [], returns false, because according to the documentation, both values ​​must be converted to a string. -> it turns out "" == "", this operation is hello to the numerical transformation, it turns out 0 == 0, and this is true. Why, then, the console gives false - ruslik

=== does not produce type casting and in the case of objects compares references . And man and man2 are two different objects - they cannot be strictly equal.

    As far as I remember, comparing these two objects with the help of operators (>, <, +, -, *, /) you get a numerical conversion , since operations to work with numbers. Therefore, you get the expected result. In addition to this, there is also a logical and string conversion . === used to check equality without type conversion, hence the two different objects will be different. Either use a recursive comparison of objects, or rather, represent the objects as a string and compare them: JSON.stringify(man1) === JSON.stringify(man2) .

    • JSON.stringify - not applicable to all objects - Grundy