2016-07-29 35 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