Question (From Eloquent Javascript 2nd Edition, Chapter 4, Exercise 4):
Write a function, deepEqual, that takes two values and returns true only if th
I am quite new to JS but this is the way I solved it:
function deepEqual(obj1, obj2) {
if (typeof obj1 === "object" && typeof obj2 === "object") {
let isObjectMatch = false;
for (let property1 in obj1) {
let isPropertyMatch = false;
for (let property2 in obj2) {
if (property1 === property2) {
isPropertyMatch = deepEqual(obj1[property1], obj2[property2])
}
if(isPropertyMatch){
break;
}
}
isObjectMatch = isPropertyMatch;
if (!isObjectMatch) {
break;
}
}
return isObjectMatch;
} else {
return obj1 === obj2;
}
}
And here are my tests:
var obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}))
// → true
console.log(deepEqual(obj, {object: 2, here: {is: "an"}}));
// → true
console.log(deepEqual(obj, {object: 1, here: {is: "an"}}));
// → false
console.log(deepEqual(obj, {objectt: 2, here: {is: "an"}}));
// → false
console.log(deepEqual(2, 2));
// → true
console.log(deepEqual(2, 3));
// → false
console.log(deepEqual(2, null));
// → false
console.log(deepEqual(null, null));
// → false
console.log(deepEqual(obj, null));
// → false
Feel that this version is a bit more readable (easier to comprehend). The logic is very similar with the top answer though. (ES6 this time)
function deepEqual(obj1, obj2) {
if(obj1 === obj2) // it's just the same object. No need to compare.
return true;
if(isPrimitive(obj1) && isPrimitive(obj2)) // compare primitives
return obj1 === obj2;
if(Object.keys(obj1).length !== Object.keys(obj2).length)
return false;
// compare objects with same number of keys
for(let key in obj1)
{
if(!(key in obj2)) return false; //other object doesn't have this prop
if(!deepEqual(obj1[key], obj2[key])) return false;
}
return true;
}
//check if value is primitive
function isPrimitive(obj)
{
return (obj !== Object(obj));
}
By the way, there is a cheater version of deep equal which works like a charm)) However, it's approximately 1.6 times slower.
As noticed by zero298, this approach is sensitive to the properties ordering and shouldn't be taken seriously
function cheatDeepEqual(obj1, obj2)
{
return JSON.stringify(obj1) === JSON.stringify(obj2);
}