This question already has answers here:
How to determine equality for two JavaScript objects?
(82 answers)
Closed 8 years ago.
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?
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.
The objects are testing for REFERENCES.
While primitives are testing for VALUE.
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;
};
Related
This question already has answers here:
How to compare arrays in JavaScript?
(55 answers)
Closed 7 years ago.
I did the following. Very confused whether they are not equal.
var arr1 = []
arr1.push(1)
arr1.push(2)
arr1.push(3)
var arr2 = [1, 2, 3]
var isSame = (arr1==arr2)
Why is isSame false? Very confused about this...
As a rule of thumb, avoid using == since it is subject to complex coercion rules. === is simpler, more efficient and less bug-prone in general. The === operator in JavaScript, for arrays and objects, compares by reference - it only returns true if two variables reference the same object.
var a = [1,2,3];
var b = [1,2,3];
var c = a;
console.log(a === b); // false
console.log(a === a); // true
console.log(a === c); // true
For numbers, bools and strings, the === operator compares by value.
var a = "hi";
var b = "hey";
var c = "hi";
console.log(a === b); // false
console.log(a === c); // true
If you want to compare two numeric arrays by value, the best way of doing it is creating a function particularly for that:
function arrayEquals(a,b){
for (var i=0, l=a.length; i<l; ++i)
if (a[i] !== b[i])
return false;
return true;
}
This will only work if your array only contains native values - strings, numbers and booleans. If you want to compare a deeper structure, a quick and dirty way is serializing it to JSON and comparing:
var a = [[1,2],3,4];
var b = [[1,2],3,4];
var c = [[1,5],3,4];
console.log(JSON.stringify(a) === JSON.stringify(b)); // true
console.log(JSON.stringify(a) === JSON.stringify(c)); // false
This will work for any structure that is a valid JSON and is actually acceptably fast for usual operations, as JSON.stringify is usually implemented natively. So, tl;dr: just use JSON.stringify on your arrays before comparing.
when comparing variables you will only compare the variables itself and not their content.
strings, numbers aswell as booleans are simple types. they are always representing their value.
objects are different. if you compare objects, you will just check if an objects reference is equal to the objects reference of the second comparator.
by comparing objects you will never ever compare the variables they contain.
objects are simply containers for even more variables.
variables can be simple types aswell as objects.
you are simply comparing two foundations to figure out if they are exactly the same.
if you really want to compare the content of an array to the content of another array you need to recursively check every variable it contains aswell.
an example..
var obj = {};
obj.foo = "bar";
(function (o) {
o.foo = "baz";
})(obj);
console.log(o.foo); // will print "baz"
when doing it with arrays you will get the same result.
you might want to check out this question: Deep comparison of objects/arrays aswell as all of the duplicates
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JavaScript compare arrays
var x = [""]
if (x === [""]) { alert("True!") }
else { alert("False!") }
For some reason, this alerts False. I cannot seem to figure out why. What can I do to make this alert True?
Two objects are equal if they refer to the exact same Object. In your example x is one Object and [""] is another. You cant compare Objects this way. This link maybe useful.
Compare values not whole arrays
...as they're objects and you're working with implicit references here. One object is stored in your x valiable which you're trying to compare (by reference) with an in-place created object (array with an empty string element). These are two objects each having it's own reference hence not equal.
I've changed your example to do what you're after while also providing the possibility to have an arbitrary number of empty strings in an array:
if (x.length && x.join && x.join("") === "")
{
alert("True!")
}
else
{
alert("False!")
}
This will return True! for any arrays like:
var x = [];
var x = [""];
var x = [null];
var x = [undefined];
var x = ["", null, undefined];
...
Arrays cannot be reliably compared this way unless they reference the same object. Do this instead:
if ( x[0] == "" )
or if you want it to be an array:
if ( x.length && x[0] == "" )
You could use toString in this case. Careful, there are some outliers where this will not work.
var x = [""]
alert(x.toString() == [""].toString()) // true
In JavaScript, two objects are equal only if they refer to the same object. Even [] == [] is false.
A probably slow but generic solution would be to compare the string representations of the two objects:
JSON.stringify(a1) == JSON.stringify(a2)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I test for an empty Javascript object from JSON?
var test= {};
var incidentReport = {
"place1": "n/a",
"place2": "n/a",
"place3": "n/a",
}
Above are the two ways my varible is going to look. Ive tryed doing the following code to test if its empty/looks like {}
if(test == "")
and tried
if(test == null)
also tried
if(!test)
Does anyone know where I am going wrong? Just a beginner to JavaScript and JSON. Is what I am doing considered back practice are there better ways to declare this empty?
Thanks for the support
Use JSON.stringify
var test= {};
if(JSON.stringify(test).length==2)
alert('null')
if(test == "")
checks if it is an empty string, so this won't work
if(test == null)
checks if it is null which is "similar" to undefined - this isn't the case
if(!test)
checks if it is a falsy value, this in not the case either.
You have to check if there exist child-elements (properties):
function isEmpty(obj) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop)) return false;
}
return true;
}
if ( isEmpty(test) ){...}
The very important point is the .hasOwnProperty() - this checks if it is a real property of the object and not only inherited through the prototype chain.
test here is an object. so you have to check if there are any prioperties/elements int his object. You can try something like below
var test= {};
function isEmptyObject(obj) {
// This works for arrays too.
for(var name in obj) {
return false
}
return true
}
alert("is this object empty?" + isEmptyObject(test));
I have this:
var g = [{a:'a'},{a:'2'},{a:'3'}]
var c = [{a:'4'},{a:'2'},{a:'5'}]
The following statement:
g[1] == c[1]
Returns false, even though the objects look the same. Is there any way I can compare them literally so it will return me true instead of false?
You could encode them as JSON:
JSON.stringify(g[1]) == JSON.stringify(c[1])
You might also be interested in the answers to this related question on identifying duplicate Javascript objects.
For a more complex option, you might look at the annotated source code for Underscore's _.isEqual() function (or just use the library).
The == operator checks for reference equality. The only way to do what you want would be a memberwise equality test on the objects.
This ought to work:
function memberwiseEqual(a, b) {
if(a instanceof Object && b instanceof Object) {
for(key in a)
if(memberwiseEqual(a[key], b[key]))
return true;
return false;
}
else
return a == b;
}
Be wary of cases like these:
var a = {};
a.inner = a; //recursive structure!
here you compare the reference in the memory ,not its value try this and you will get true :
g[1]['a'] === c[1]['a']
In JavaScript variables which are objects (including arrays) are actually references to the collection. So when you write var x = { a: 2 } and var y = { a: 2 } then x and y become references to two different objects. So x will not equal y. But, if you did y = x then they would (because they would share the same reference). But then if you altered either object the other would be altered too.
So, when dealing with objects and arrays, by saying == you are checking if the two references are the same. In this case they are not.
This question already has answers here:
Why isn't [1,2,3] equal to itself in Javascript? [duplicate]
(6 answers)
Closed 6 years ago.
The following is done in Firebug:
>>> [1, 2] == [1, 2]
false
>>> ({a : 1}) == ({a : 1})
false
I thought Javscript has some rule that says, if an Object or Array has the same references to the same elements, then they are equal?
But even if I say
>>> foo = {a : 1}
Object { a=1}
>>> [foo] == [foo]
false
>>> ({a: foo}) == ({a: foo})
false
Is there a way to make it so that it can do the element comparison and return true?
{ } and [ ] are the same as new Object and new Array
And new Object != new Object (ditto with Array) because they are new and different objects.
If you want to know whether the content of two arbitary objects is the "same" for some value of same then a quick (but slow) fix is
JSON.parse(o) === JSON.parse(o)
A more elegant solution would be to define an equal function (untested)
var equal = function _equal(a, b) {
// if `===` or `==` pass then short-circuit
if (a === b || a == b) {
return true;
}
// get own properties and prototypes
var protoA = Object.getPrototypeOf(a),
protoB = Object.getPrototypeOf(b),
keysA = Object.keys(a),
keysB = Object.keys(b);
// if protos not same or number of properties not same then false
if (keysA.length !== keysB.length || protoA !== protoB) {
return false;
}
// recurse equal check on all values for properties of objects
return keysA.every(function (key) {
return _equal(a[key], b[key]);
});
};
equals example
Warning: writing an equality function that "works" on all inputs is hard, some common gotchas are (null == undefined) === true and (NaN === NaN) === false neither of which I gaurd for in my function.
Nor have I dealt with any cross browser problems, I've just assumed ES5 exists.
To see what kind of code is necessary to do the deep equality you are talking about, check out Underscore.js's _.isEqual function or QUnit's deepEqual implementation.
Its because javascript object literals do not share the same pointers. Instead a new pointer gets created for each one. Consider the following example:
>>> ({a : 1}) == ({a : 1})
false
... but ...
>>> obj = ({a : 1});
Object
>>> obj == obj
true
obj is a pointer to the litteral object { a : 1 }. So this works because the pointers are the same when you compare them
You are comparing different objects.
>>> var a = [1,2] var b = [1,2]
>>> a == b
false
>>> a == a
true
If you want to test array equality you might want to use some library or just write the test yourself.