Reputation: 3617
Let's say I have two objects that only have primitives as properties for members (e.g. the object has no functions or object members):
var foo = {
start: 9,
end: 11
};
var bar = {
start: 9,
end: 11
};
Given two objects like this, I want to know if all their members have the same values.
Right now I'm simpling doing:
if (foo.start === bar.start && foo.end == bar.end) {
// same member values
}
But I'm going to have to work with objects that may have dozens of these primitive members.
Is there anything built into JavaScript to easily allow me to compare them? What's the easiest way to compare all their values?
Upvotes: 0
Views: 196
Reputation: 4736
Y'know, something's just occurred to me. Basic object literals are called JSON. The easiest way to compare those two objects is
function equalObjects(obj1, obj2) {
return JSON.stringify(obj1) === JSON.stringify(obj2);
}
If you need to use this in a browser that doesn't have native JSON support, you can use the open source JSON scripts
Upvotes: 0
Reputation: 1074475
If both objects are Object
s (e.g., created via literal notation [{}
] or new Object
, not by [say] new Date
), you can do it like this:
function primativelyEqual(a, b) {
var name;
for (name in a) {
if (!b.hasOwnProperty(name) || b[name] !== a[name]) {
// `b` doesn't have it or it's not the same
return false;
}
}
for (name in b) {
if (!a.hasOwnProperty(name)) {
// `a` doesn't have it
return false;
}
}
// All properties in both objects are present in the other,
// and have the same value down to the type
return true;
}
for..in
iterates over the names of the properties of an object. hasOwnProperty
tells you whether the instance itself (as opposed to a member of its prototype chain) has that property. !==
checks for any inequality between two values without doing any type coercion. By looping through the names of the properties of both objects, you know that they have the same number of entries.
You can shortcut this a bit if the implementation has the new Object.keys
feature from ECMAScript5:
function primativelyEqual(a, b) {
var name, checkedKeys;
checkedKeys = typeof Object.keys === "function";
if (checkedKeys && Object.keys(a).length !== Object.keys(b).length) {
// They don't have the same number of properties
return false;
}
for (name in a) {
if (!b.hasOwnProperty(name) || b[name] !== a[name]) {
// `b` doesn't have it or it's not the same
return false;
}
}
if (!checkedKeys) {
// Couldn't check for equal numbers of keys before
for (name in b) {
if (!a.hasOwnProperty(name)) {
// `a` doesn't have it
return false;
}
}
}
// All properties in both objects are present in the other,
// and have the same value down to the type
return true;
}
But both versions of the above assume that the objects don't inherit any enumerable properties from their prototypes (hence my opening statement about their being Object
s). (I'm also assuming no one's added anything to Object.prototype
, which is an insane thing people learned very quickly not to do.)
Definitely possible to refine that more to generalize it, and even make it descend into object properties by the same definition, but within the bounds of what you described (and within the bounds of most reasonable deployments), that should be fine.
Upvotes: 6
Reputation: 887469
You can use a for in
loop to loop through every property in an object.
For example:
function areEqual(a, b) {
for (var prop in a)
if (a.hasOwnProperty(prop) && a[prop] !== b[prop])
return false;
return true;
}
Any properties in b
but not a
will be ignored.
Upvotes: 3