2016-07-29 60 views
1

我使用JavaScript对象的深比较lodash isEqual功能。它要求对象具有相同的原型算作相等,如下面的会话与节点REPL显示:检查JS深平等而不考虑的原型(优选在lodash)

> const isEqual = require('lodash').isEqual 
undefined 
> isEqual({a:3},{a:3}) 
true 
> class Foo { constructor(x) {this.a = x} } 
[Function: Foo] 
> isEqual(new Foo(3), new Foo(3)) 
true 
> isEqual({a:3}, new Foo(3)) 
false 

有没有一种简单的方法做深做比较忽视的原型?它应该对日期进行特殊比较;我只想在lodash会做递归比较的情况下,不关心原型是否有区别。很明显,我可以自己编写代码,但我使用lodash而不必做那种事情。我也想过这样做

isEqual(JSON.parse(JSON.stringify(obj1)), JSON.parse(JSON.stringify(obj2))) 

也许它是好的,但它似乎很重要。

+0

你可以只用'JSON.stringify({A:3})=== JSON.stringify(新富(3 ))'在最后一个例子中; – user3335966

+0

这不起作用。大多数浏览器对于'JSON.stringify({a:1,b:2})'和'JSON.stringify({b:2,a:1})'会给出不同的结果。 – gmr

回答

0

这不是 “一个简单的方法”,但它可以帮助:

function eq(a, b){ 
    if(!_.isObject(a) || !_.isObject(b)) return 'Error! Only for objects.'; 
    var keysA = Object.keys(a).sort(); 
    var keysB = Object.keys(b).sort(); 
    if(!_.isEqual(keysA, keysB)) return false; 
    for(var i = 0, l = keysA.length; i < l; i++){ 
     if(
      (_.isObject(a[keysA[i]]) && _.isObject(b[keysB[i]]) && !eq(a[keysA[i]], b[keysB[i]])) || 
      (!_.isObject(a[keysA[i]]) && !_.isObject(b[keysB[i]]) && a[keysA[i]] !== b[keysB[i]]) || 
      (_.isObject(a[keysA[i]]) !== _.isObject(b[keysB[i]])) 
     ) return false; 
    } 
    return true; 
} 

eq({a: 1}, new Foo(1));   //true 
eq({a: 1}, new Foo(2));   //false 
eq({a: 1, b: 2}, {b: 2, a: 1}); //true 
eq({a: 1, b: 3}, {b: 2, a: 1}); //false 

eq({a: {a: 1}}, {a: new Foo(1)})//true 
+0

谢谢。它看起来像这个解决方案将在日期分解,也许在其他情况下,我没有考虑过(或可能没有)。我想如果我要去定义这样一个更复杂的函数的路线,我会从lodash实现开始并修改它,或者可能根据lodash的'isEqualWith'函数做一些事情。另外,我已经看到了一些“规范的JSON.stringify”函数来排序这些键。不过,现在,我提到的“总体”解决方案似乎工作正常,所以我坚持,直到它给我的问题:) – gmr