我希望能够获得两个JavaScript对象图之间所有差异的列表,并带有出现变化的属性名称和值。
对于其价值而言,这些对象通常以JSON的形式从服务器中检索,并且通常不超过几层深度(即,它可能是一个本身具有数据的对象数组,然后是与其他数据对象组成的数组) 。
我不仅希望看到基本属性的更改,还希望看到数组成员数量的差异,等等。
如果我没有得到答案,我可能最终会自己写这个,但希望有人已经完成了这项工作或知道有人做了。
编辑:这些对象通常在结构上非常接近,因此我们不是在谈论彼此完全不同但可能具有3或4个增量的对象。
查看现有答案后,我注意到https://github.com/flitbit/diff库尚未作为解决方案列出。
根据我的研究,从主动开发,贡献和解决分歧对象挑战的角度看,这个库似乎是最好的。这对于在服务器端创建差异并仅将更改的位传递给客户端非常方便。
这里是我的问题的部分,幼稚的解决方案,我会在进一步开发时对其进行更新。
function findDifferences(objectA, objectB) {
var propertyChanges = [];
var objectGraphPath = ["this"];
(function(a, b) {
if(a.constructor == Array) {
// BIG assumptions here: That both arrays are same length, that
// the members of those arrays are _essentially_ the same, and
// that those array members are in the same order...
for(var i = 0; i < a.length; i++) {
objectGraphPath.push("[" + i.toString() + "]");
arguments.callee(a[i], b[i]);
objectGraphPath.pop();
}
} else if(a.constructor == Object || (a.constructor != Number &&
a.constructor != String && a.constructor != Date &&
a.constructor != RegExp && a.constructor != Function &&
a.constructor != Boolean)) {
// we can safely assume that the objects have the
// same property lists, else why compare them?
for(var property in a) {
objectGraphPath.push(("." + property));
if(a[property].constructor != Function) {
arguments.callee(a[property], b[property]);
}
objectGraphPath.pop();
}
} else if(a.constructor != Function) { // filter out functions
if(a != b) {
propertyChanges.push({ "Property": objectGraphPath.join(""), "ObjectA": a, "ObjectB": b });
}
}
})(objectA, objectB);
return propertyChanges;
}
这是如何使用它以及将提供的数据的示例(请原谅长的示例,但是我想使用相对平凡的东西):
var person1 = {
FirstName : "John",
LastName : "Doh",
Age : 30,
EMailAddresses : [
"[email protected]",
"[email protected]"
],
Children : [
{
FirstName : "Sara",
LastName : "Doe",
Age : 2
}, {
FirstName : "Beth",
LastName : "Doe",
Age : 5
}
]
};
var person2 = {
FirstName : "John",
LastName : "Doe",
Age : 33,
EMailAddresses : [
"[email protected]",
"[email protected]"
],
Children : [
{
FirstName : "Sara",
LastName : "Doe",
Age : 3
}, {
FirstName : "Bethany",
LastName : "Doe",
Age : 5
}
]
};
var differences = findDifferences(person1, person2);
至此,如果将differences
数组序列化为JSON,则其外观将是这样:
[
{
"Property":"this.LastName",
"ObjectA":"Doh",
"ObjectB":"Doe"
}, {
"Property":"this.Age",
"ObjectA":30,
"ObjectB":33
}, {
"Property":"this.EMailAddresses[1]",
"ObjectA":"[email protected]",
"ObjectB":"[email protected]"
}, {
"Property":"this.Children[0].Age",
"ObjectA":2,
"ObjectB":3
}, {
"Property":"this.Children[1].FirstName",
"ObjectA":"Beth",
"ObjectB":"Bethany"
}
]
this
值中的Property
指的是被比较对象的根。因此,该解决方案还不是我所需要的,但是距离还很遥远。 希望这对外面的人很有用,如果您有任何改进的建议,我将全力以赴;我昨晚(即今天清晨)写了这篇文章,可能有些事情我完全忽略了。
谢谢。
解决方案1
odiff
:https://github.com/Tixit/odiff。这是一个例子: