Edit: This is not a duplicate question. My function is different and doesn't use direct object comparison methods.
I am working through Eloquent Javascript book and in the fourth chapter, the last exercise required a function deepEqual that takes two arguments and compares them.
- If the arguments are different types, it should return false.
- If the arguments are the same type and same value, it should return true otherwise, return false.
- If the arguments are both objects, their properties and values should be compared. The function call should return true if both objects have same properties and value in the same order. For example, if we have the following objects:
object1 = {a: 1, b: 2}, object2 = {a: 1, b: 2}, object3 = {a: 2, b: 1}
, comparing object1 and object2 should return true, but comparing object1 and object3 should return false. - Lastly, if the objects have nested objects as parameters, a recursive call of deepEqual to compare the nested objects.
So, here is my solution. It is quite convoluted with if/else statements, pardon it.
function deepEqual(obj1, obj2){
var checkForSameTypes = (typeof obj1 === typeof obj2);
if(checkForSameTypes === true){
//same type but not objects
if(typeof obj1 !== "object" && typeof obj2 !== "object") {
if(obj1 == obj2){
return true;
}else{
return false;
}
// same type and objects
}else if(typeof obj1 === "object" && typeof obj2 === "object"){
//loop first object and compare properties with 2nd object
for(var prop in obj1){
if(obj2.hasOwnProperty(prop)) {
//if 2nd object has property "prop" compare
if(typeof obj1[prop] === "object" && typeof obj2[prop] === "object"){
//recursive call
deepEqual(obj1[prop], obj2[prop]);
}else if(obj1[prop] === obj2[prop]) {
//loop goes on to the next property
continue;
}else if(obj1[prop] !== obj2[prop]){
return false;
}
//it doesn't have property "prop" so return false
} else {
return false;
}
}
//finishes loop and all properties are the same
return true;
}
// they are not the same types so return false
} else {
return false;
}
}
PROBLEM
The function works fine except when an argument is an object with nested objects. Take these objects for example
var type = {go: {inside: "yes"}, come: 2}
var see = {go: {inside: "no"}, come: 2}
var fine = {when: 3, go: 4};`
When I compare type
and see
with a call to deepEqual(type,see);
, this returns true
which is wrong because the value of the property of the nested object go
is different.
I have gone through the entire code on paper, line by line and do not know what I have to do, or if the recursive call isn't working to compare the properties rightly or I just don't have the knowledge yet.
Can anyone offer a solution? or and if possible a better way or thinking process to solve this case?
Note: The code only compares object properties and values. It doesn't need to compare constructors or prototypes.