Monday, June 13, 2016
Write a function that runs a deep comparison on two objects
Just like the title says, we need a function that can run a deep comparison on two objects to see if they equal each other.
In case you don't know this:
var obj1 = {
name : "Sam"
}
var obj2 = {
name : "Sam"
}
obj1 === obj2
// false
That's right, obj2 does not equal obj2 even though they are identical. This is because objects are passed by reference, not as values. Variables are the opposite.
var banana = 5;
var apple = 5;
apple === banana;
// true
The variable banana holds the value 5, as does apple, so when you compare the two the question is does 5 equal 5, and that is true.
However, the object does not hold a value. It holds an address to a location in memory where the value/ values are stored. If memory addresses were the same as home addresses, then the object might hold something like 832 West Maple St., APT 9.
The address where the values for obj1 are stored might be 99283746, for example.
The address where the values for obj2 are stored might be 23827342834, for example.
So, when we compare obj1 === obj2, what we are comparing is 99283746 === 23827342834 which is false.
This is what is meant by objects are passed by reference. Take this example :
var obj1 = {
name : "Sam"
}
var obj2 = {
name : "Sam"
}
var obj3 = obj1;
obj1 === obj3;
// true;
When I assign the var obj3 to be equal to obj1, the address to the memory which holds the values for obj1 is passed to obj3, so obj3 now equals 99283746.
Just imagine that the browser knocks on the door of obj1, because it wants to see inside it:
Knock, knock. Who's there? The browser? The browser who? The web browser, I want to see inside you. Okay, go to 99283746.
So, let's create a function that will compare not the addresses of two objects, but there actual properties and values.
Tip, arrays are also objects. A for in loop can be used on arrays too.
A little recursion will help.
All of these should return true, except for the second one :
var obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
console.log(deepEqual(obj, {here: 1, object: 2}));
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
console.log(deepEqual([5, {names : [{d :"sam"},{s : "mike"},{da : "joen"}]}], [5, {names : [{d :"sam"},{s : "mike"},{da : "joen"}]}]));
I'll put the solution in the comments.
Subscribe to:
Post Comments (Atom)
function deepEqual(a, b) {
ReplyDeleteif (a === b) return true;
if (a == null || typeof a != "object" ||
b == null || typeof b != "object")
return false;
var propsInA = 0, propsInB = 0;
for (var prop in a)
propsInA += 1;
for (var prop in b) {
propsInB += 1;
if (!(prop in a) || !deepEqual(a[prop], b[prop]))
return false;
}
return propsInA == propsInB;
}