Javascript: Why are two objects not equal? [duplicate] - javascript

This question already has answers here:
Why are two identical objects not equal to each other?
(9 answers)
Closed 5 months ago.
I know there are similar questions to this on SO, but none of them provide the answer I am looking for.
In JavaScript, if you do the following, the result will be false:
I know it is to do with how JavaScript is defined in the spec, but why is it like that? It is counter-intuitive.
If ("string" === "string") results in being true, then why doesn't ({ } === { }) result in being true?
I saw somewhere that the equality algorithm was designed to be similar to that of C++ or C#, but that's like inventing a brand new engine that uses 1/10th of the fuel and not using it purely for consistency with other cars.
Why was JavaScript defined in this way? Is there a reason behind this decision? Or was it just so it was seen doing the done thing?

{} is a literal to create object in javascript. That is you can replace
var obj = new Object();
with
var obj = {};
So any time you use {} you are creating a new object.
The line you mentioned, {} == {} creates two different objects and both has no properties. Identically they are same, like if you have equals(obj1, obj2) method which compares properties of both obj1 and obj2 and it should return true if both has same value for all properties.
But == operator will not check for properties. It checks if both the objects are pointing to same object/reference.
Whereas
var obj1 = {};
obj2 = obj1;
console.log(obj2 == obj1); //returns true
returns true because obj1 and obj2 are pointing to same reference.
Finally, regarding string "abc" == "abc", here == operator looks for actual string contents and returns true/false based on it.

Strings are immutable, so two strings that have the same contents are functionally indistinguishable.
But objects and arrays can be modified, so just because they happen to have the same contents at some particular time doesn't mean they're the same. You can modify them and they'll then be different.
Another way to put this is that if obj1 == obj2 is true, then when you do obj1.x = 1, it will also change obj2.x.

because a string in javascript even if being an object is considered a primitive, just like a integer or a boolean, and those are always compared by value, because that is what a primitive is, a simple atomic value.. so "string" == "string", 1 = 1 and true == true,
but objects are complex types, they are an aggregate of primitives, and the rules to compare that aggregate, cannot be simplified to standard, is {name:'a',address:'b',phone:'c'} != {name:'a',address:'b'} because does not have the same number of attributes? then in that case will {name:'x',address:'y'} == {name:'a',address'b'}? they have the same attributes, but with different values, or to make it more complex {name:'x',address'y'} == {address:'y',name:'c'}.. does the order matter..
so if the comparison of complex objects can't be done in a simple standard way, it is better to leave to the programmer to implement the rule that applies to the situation..
so what comparison can the language implement that is at least helpful and reliable.. comparing if two object references are equal this will allow to make validations like obj == null or obj == this or if obja == objb so we can at least know of what object/reference are we talking about..
so in summary primitive will always be compared by their value, and complex types are compared by their reference, this is how most languages do, and is not by an inspirations of c++ or whatever is just 'the rules of the game'

Related

Dynamic JSON is not equal to Static JSON [duplicate]

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?
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.
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.
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.
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
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.
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).
===, 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.
This is a workaround: Object.toJSON(obj1) == Object.toJSON(obj2)
By converting to string, comprasion will basically be in strings
In Javascript each object is unique hence {} == {} or {} === {} returns false. In other words Javascript compares objects by identity, not by value.
Double equal to ( == ) Ex: '1' == 1 returns true because type is excluded
Triple equal to ( === ) Ex: '1' === 1 returns false compares strictly, checks for type even

Why are two identical functions not equal? [duplicate]

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?
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.
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.
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.
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
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.
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).
===, 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.
This is a workaround: Object.toJSON(obj1) == Object.toJSON(obj2)
By converting to string, comprasion will basically be in strings
In Javascript each object is unique hence {} == {} or {} === {} returns false. In other words Javascript compares objects by identity, not by value.
Double equal to ( == ) Ex: '1' == 1 returns true because type is excluded
Triple equal to ( === ) Ex: '1' === 1 returns false compares strictly, checks for type even

== or ===, which one should I use to compare two objects in javascript?

I do not mean deep comparison.
I just want to know if two variables refer to the same instance. Should I use a==b or a===b? Can two variables point to the same memory but with different types? Because javascript has no such concept as class in C++, I do not know what an object's type is. Do all objects have the same type: "object" so === decides their types are equal? If so, === would be the same as ==.
From A Drip of Javascript: Object Equality in Javascript:
... Primitives like strings and numbers are compared by their value, while objects like arrays, dates, and plain objects are compared by their reference. That comparison by reference basically checks to see if the objects given refer to the same location in memory. Here is an example of how that works.
var jangoFett = {
occupation: "Bounty Hunter",
genetics: "superb"
};
var bobaFett = {
occupation: "Bounty Hunter",
genetics: "superb"
};
var callMeJango = jangoFett;
// Outputs: false
console.log(bobaFett === jangoFett);
// Outputs: true
console.log(callMeJango === jangoFett);
you should use === because it will avoid error exceptions hard to be found. and about time consuming, === is better as well.

Why equality without type coercion return false for === [duplicate]

This question already has answers here:
Which equals operator (== vs ===) should be used in JavaScript comparisons?
(48 answers)
JavaScript comparison operators: Identity vs. Equality
(4 answers)
Closed 8 years ago.
Why does the following statement return false in JavaScript?
new String('hello') === new String('hello')
Two String objects will always be unequal to each other. Note that JavaScript has string primitive values as well as a String constructor to create wrapper objects. All object equality comparisons (especially with ===) are carried out as a test for reference equality. References to two different objects will of course never be equal to each other.
So "hello" === "hello" will be true because those are string primitives.
You are comparing object instances, which is not like a string comparison ('hello' === 'hello') Comparing objects in Javascript is actually comparing the memory addresses of the objects and will always return false because memory addresses are different for each object.
Compare the string values instead of the object instance - jsFiddle
( String('hello') === String('hello') ) // returns true due to comparing strings
Strictly comparing two objects - false not the same object
new String('hello') === new String('hello')
Strictly comparing two strings - true, same returned value and same returned type
String('hello') === String('hello')
It evaluates to false because you're comparing two different objects: new will create a new object.
Related post: What is the 'new' keyword in JavaScript? Which explains in its (extensive) answer:
It [new] is 4 things:
It creates a new object. The type of this object, is simply object.
It sets this new object's internal, inaccessible, [[prototype]] property to be the constructor function's external, accessible,
prototype object (every function object automatically has a prototype property).
It executes the constructor function, using the newly created object whenever this is mentioned.
It returns the newly created object, unless the constructor function returns a non-primitive value. In this case, that
non-primitive value will be returned.
You are asking javascript to compare two different instances of the variable, not the string value that lives inside the variable.
So for example, lets say I have a piece of paper with the word "Hello World" written on it (Paper1) and my brother has a different piece of paper with the word "Hello World" written on it (Paper2).
When you say is Paper1 === Paper2 you will get false, beacuse no they are not the exact same piece of paper, even though the words written on the paper are the same.
If you where to say Paper1.toString() === Paper2 .toString() you would get true, beacuse we are comparing the words written on the paper, not the actual paper itself.
typeof(new String()) === 'object';
==> true
(new Object()) === (new Object());
==> false
Any "object" structure in the "Heap" is unique;
Heap vs. Stack
Your code essentially says "Take a piece of paper and write 'hello' on it. Take another piece of paper and write 'hello' on that. Are they the same piece of paper?"
Also if you do
if ( { hello: 1 } === { hello: 1 } ){ console.log( "yay" ); }
the console.log never happen, because it's an object.
You can compare 2 literal objects (as my first example) by making a loop on these objects and when you find a difference you know the result.
It's more difficult to do this trick in an instantiated object, compare 2 functions it's crazy.
But if JavaScript don't do it for you it's because this is very heavy, you have check each type of each attributes to stringify it if it's a function etc... and obviously it's not useful to do it.
You can use instanceof if you want to check 2 objects "origins", because typeof will return you "object".
And for testing 2 "new String" object you have to use toString
new String( "hello" ).toString() == new String( "hello" ).toString()
or if you want to check the object without testing the attributes
new String( "hello" ) instanceof String && new String( "hello" ) instanceof String
is true.
The link given by BeyelerStudios explain perfectly what the new do, hope it'll help.

Check if object is in array not working [duplicate]

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?
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.
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.
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.
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
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.
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).
===, 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.
This is a workaround: Object.toJSON(obj1) == Object.toJSON(obj2)
By converting to string, comprasion will basically be in strings
In Javascript each object is unique hence {} == {} or {} === {} returns false. In other words Javascript compares objects by identity, not by value.
Double equal to ( == ) Ex: '1' == 1 returns true because type is excluded
Triple equal to ( === ) Ex: '1' === 1 returns false compares strictly, checks for type even

Categories