Reputation: 13372
Something like this
var test = {a: 'a', b: 'b'}; var test2 = {a: 'a', b: 'b'};
var a = [];
a.push(test);
alert($.inArray(test2, a));
Test2 = -1
Test = 0
Why is this? The objects should be identical right? What kind of comparison is it doing?
EDIT:
Clarifying some things. All the answers below are extremely informative. I am using an array to store a runtime pair of values a "page" and a "directory". These are normally separated unrelated values. I wanted to setup a array of certain pair values and be able to get those two unrelated, form that key pair relationship by creating an object, then searching an array of "allowed" pairs using this method.
I'll use the custom search function for this. Thanks SO!
Upvotes: 0
Views: 426
Reputation: 27060
When you write {a: 'a', b: 'b'}
, you are creating a new object in JavaScript. When you write it again, you create another object, although both objects contains the same values. When you attribute it to variables, the variables just contains references ("pointers") for each object. When you write
var test = {a: 'a', b: 'b'};
var test2 = {a: 'a', b: 'b'};
You got two variables pointing to two objects:
When you compare the two variables, you just compare the pointers. Since the two objects are different, the pointers are different and the result of the comparison is false
. OTOH, if you have done the code below
var test = {a: 'a', b: 'b'};
var test2 = test;
the result is that test
and test2
point to the same object and are equal.
(More about references on Wikipedia. It would be good to read about pointers too).
What you want to do use a deep comparison in the $.inArray()
function. If your objective would be to just compare values, I would recommend you to use the Underscore.js isEqual()
function. Since it is not the case, and $.inArray()
does not accept a comparator as parameter, I bet you will have to implement it manually:
function inArray(element, array) {
for (var key in array) {
if (_.isEqual(element, array[key])) {
return true;
}
}
return false;
}
EDIT: well, it would be awesome if our function does receive the comparator as a parameter!
function inArray(element, array, cmp) {
if (typeof cmp != "function") {
cmp = function (o1, o2) {
return o1 == o2;
};
}
for (var key in array) {
if (cmp(element, array[key])) {
return true;
}
}
return false;
}
Testing in Node.js:
> inArray(test2, a)
false
> inArray(test2, a, function(o1, o2){return o1 === o2;})
false
> inArray(test2, a, _.isEqual)
true
Of course, this brings more complexity for your specific problem, so you do not need to use it. However, I think it may be valid to register the idea :)
Upvotes: 1
Reputation: 93040
There are two different objects (even though containing the same values).
test == test2
evaluates to false
.
Check How do you determine equality for two JavaScript objects?
Upvotes: 0
Reputation: 82624
You can compare each element:
function compareObjects(a, b) {
var areEqual = true;
for (var key in a) {
if (b[key] !== a[key]) {
areEqual = false;
break;
}
}
for (var key in b) {
if (b[key] !== a[key]) {
areEqual = false;
break;
}
}
return areEqual;
}
Or maybe serialize the records and string compare:
JSON.stringify({a: 1, b: 2}) === JSON.stringify({"a": 1, "b": 2}); // true
Upvotes: 1
Reputation: 707546
a
is an array who's first element is the test object.
inArray
tests to see if any array element in the passed in array is the same as the test
value. So, you're looking in the a array for the test2
object. But, the test2
object is not in that array. test2
may have the same contents as test
, but it isn't the same object.
In summary, your issue is that:
test != test2
because they are not the same object. Their contents may be the same, but they are not the same object.
If you want to compare two objects for the same contents, see this previous post: Object comparison in JavaScript.
Upvotes: 0