问题
I'm working my way through the 3rd edition of Eloquent JavaScript and although I've seen one or two various answers on SO that seem almost identical in execution logic to mine that work mine just doesnt seem to no matter how I tweek it.
THE GOAL: create a deep comparison function that can compare two objects and determine based on their properties if theyre different instances of the same type of object (same keys and values) regardless of reference...
Can anyone spot the bug in my code?
function deepEqual(a,b){
if((typeof a=='object'&& a!=null)&&(typeof b=='object'&& b!=null)){
if(Object.keys(a).length != Object.keys(b).length){return false}
for(let key in a){
if(a[key]==b[key]){
if(!deepEqual(a[key],b[key])){return false}
}else{
return false
}
}
return true
}else if(a!==b){return false}
else{return true}
}
var obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
// → true (reads true currently)
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false (reads false currently)
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
// → true (reads false currently)
回答1:
The bug was here:
if (a[key] == b[key])
if they're objects the condition may return false even if they're "equal".
function deepEqual(a, b) {
if (a && b && typeof a == 'object' && typeof b == 'object') {
if (Object.keys(a).length != Object.keys(b).length) return false;
for (var key in a) if (!deepEqual(a[key], b[key])) return false;
return true;
} else return a === b
}
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
回答2:
Looks like you just need to tweak your for-loop logic to catch objects like so (using your own logic):
for(let key in a){
let aValue = a[key]
let bValue = b[key]
if (typeof aValue == 'object' && typeof bValue == 'object') {
// catches nested objects and recursively assesses deep equality
if(!deepEqual(aValue, bValue)) return false
}
else if (aValue !== bValue) {
// if the values are not objects, catches if they are not equal
return false
}
}
You can play with this, here: https://jsbin.com/wotapezuwo/edit?js,console
来源:https://stackoverflow.com/questions/48728515/deep-compare-javascript-function