Javascript:深度比较
Javascript: Deep Comparison
我正在检查这个问题
提问者的解决方案没有让我信服所以我试着分析问题并得出了
var obj = {here: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1}));
// → false
console.log(deepEqual(obj, {here: 2}));
// → true
function deepEqual(a,b)
{
if( (typeof a == 'object' && a != null) &&
(typeof b == 'object' && b != null) )
{
var count = [0,0];
for( var key in a) count[0]++;
for( var key in b) count[1]++;
if( count[0]-count[1] != 0) {console.log('1');return false;}
for( var key in a)
{
if(!(key in b) || !deepEqual(a[key],b[key])) {console.log('2');return false;}
}
for( var key in b)
{
if(!(key in a) || !deepEqual(b[key],a[key])) {console.log('3');return false;}
}
}
console.log('a:'+a+' b:'+b);
return a===b;
}
obj === { here:2 }
此代码未通过最后一次测试(console.log(deepEqual(obj, {here: 2})))但是如果对象具有分别相同的键和值,尽管它们是不同的实例,但考虑对象深度相等的逻辑在记忆中并不能说服我。是我的 'solution' 有问题还是错误在于练习的假设?我链接的问题中提到的代码是否有效?
hikinthru 忘记提及的资源 ( http://eloquentjavascript.net/04_data.html#exercise_deep_compare )
"Deep equality",这就是你所链接的问题所谈论的内容,"strict equality" 是两个不同的东西。 "Deep equality" 意味着,如你所说,"equal keys and equal values." "Strict equality" 对于对象意味着 "same instance." 严格相等意味着深度相等,但是对象可以深度相等而不是严格相等。
您的代码效率有点低,因为您只需要一个循环,但如果您在 else
块中检查 a === b
并在 [=14= 之后检查 return true
,它会正常运行] 循环。这是因为您应该将对象与原始值(如字符串和数字)分开处理。为了清晰起见,我删除了一些日志记录,并尽量保持您的风格。
var obj = {here: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1}));
// → false
console.log(deepEqual(obj, {here: 2}));
// → true
console.log(obj === { here:2 });
// → false
function deepEqual(a,b)
{
if( (typeof a == 'object' && a != null) &&
(typeof b == 'object' && b != null) )
{
var count = [0,0];
for( var key in a) count[0]++;
for( var key in b) count[1]++;
if( count[0]-count[1] != 0) {return false;}
for( var key in a)
{
if(!(key in b) || !deepEqual(a[key],b[key])) {return false;}
}
for( var key in b)
{
if(!(key in a) || !deepEqual(b[key],a[key])) {return false;}
}
return true;
}
else
{
return a === b;
}
}
我正在检查这个问题
var obj = {here: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1}));
// → false
console.log(deepEqual(obj, {here: 2}));
// → true
function deepEqual(a,b)
{
if( (typeof a == 'object' && a != null) &&
(typeof b == 'object' && b != null) )
{
var count = [0,0];
for( var key in a) count[0]++;
for( var key in b) count[1]++;
if( count[0]-count[1] != 0) {console.log('1');return false;}
for( var key in a)
{
if(!(key in b) || !deepEqual(a[key],b[key])) {console.log('2');return false;}
}
for( var key in b)
{
if(!(key in a) || !deepEqual(b[key],a[key])) {console.log('3');return false;}
}
}
console.log('a:'+a+' b:'+b);
return a===b;
}
obj === { here:2 }
此代码未通过最后一次测试(console.log(deepEqual(obj, {here: 2})))但是如果对象具有分别相同的键和值,尽管它们是不同的实例,但考虑对象深度相等的逻辑在记忆中并不能说服我。是我的 'solution' 有问题还是错误在于练习的假设?我链接的问题中提到的代码是否有效?
hikinthru 忘记提及的资源 ( http://eloquentjavascript.net/04_data.html#exercise_deep_compare )
"Deep equality",这就是你所链接的问题所谈论的内容,"strict equality" 是两个不同的东西。 "Deep equality" 意味着,如你所说,"equal keys and equal values." "Strict equality" 对于对象意味着 "same instance." 严格相等意味着深度相等,但是对象可以深度相等而不是严格相等。
您的代码效率有点低,因为您只需要一个循环,但如果您在 else
块中检查 a === b
并在 [=14= 之后检查 return true
,它会正常运行] 循环。这是因为您应该将对象与原始值(如字符串和数字)分开处理。为了清晰起见,我删除了一些日志记录,并尽量保持您的风格。
var obj = {here: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1}));
// → false
console.log(deepEqual(obj, {here: 2}));
// → true
console.log(obj === { here:2 });
// → false
function deepEqual(a,b)
{
if( (typeof a == 'object' && a != null) &&
(typeof b == 'object' && b != null) )
{
var count = [0,0];
for( var key in a) count[0]++;
for( var key in b) count[1]++;
if( count[0]-count[1] != 0) {return false;}
for( var key in a)
{
if(!(key in b) || !deepEqual(a[key],b[key])) {return false;}
}
for( var key in b)
{
if(!(key in a) || !deepEqual(b[key],a[key])) {return false;}
}
return true;
}
else
{
return a === b;
}
}