两个对象之间的通用深度比较
深度比较两个对象涉及识别它们之间的更改,包括添加、更新和删除。这可能很复杂,特别是对于嵌套对象和数组。
通用深度差异的现有库或代码
一种方法是实现一个通用的 deepDiffBetweenObjects 方法,该方法返回指示更改的对象如下:
{add:{...},upd:{...},del:{...}}
但是,需要更精细的表示来捕获内的更新对象结构。
使用更新的对象结构增强表示
改进的表示使用与更新的对象 (newObj) 相同的对象结构,但将属性值转换为对象:
{type: '<update|create|delete>', data: <propertyValue>}
例如,如果 newObj.prop1 = '新值' 并且oldObj.prop1 = '旧值',结果将是:
returnObj.prop1 = {type: 'update', data: 'new value'}
处理数组
数组引入了额外的复杂性,因为确定等价性并不简单。例如,数组:
[1,[{c: 1},2,3],{a:'hey'}]
和
[{a:'hey'},1,[3,{c: 1},2]]
应被视为相等。深度值相等的检查可能很复杂,并且有效地表示数组更改也具有挑战性。
示例实现
这是一个可以执行通用深度比较的类的实现:
var deepDiffMapper = function () { return { map: function(obj1, obj2) { if (this.isFunction(obj1) || this.isFunction(obj2)) { throw 'Invalid argument. Function given, object expected.'; } if (this.isValue(obj1) || this.isValue(obj2)) { return { type: this.compareValues(obj1, obj2), data: obj1 === undefined ? obj2 : obj1 }; } var diff = {}; for (var key in obj1) { if (this.isFunction(obj1[key])) { continue; } var value2 = undefined; if (obj2[key] !== undefined) { value2 = obj2[key]; } diff[key] = this.map(obj1[key], value2); } for (var key in obj2) { if (this.isFunction(obj2[key]) || diff[key] !== undefined) { continue; } diff[key] = this.map(undefined, obj2[key]); } return diff; }, compareValues: function (value1, value2) { if (value1 === value2) { return this.VALUE_UNCHANGED; } if (this.isDate(value1) && this.isDate(value2) && value1.getTime() === value2.getTime()) { return this.VALUE_UNCHANGED; } if (value1 === undefined) { return this.VALUE_CREATED; } if (value2 === undefined) { return this.VALUE_DELETED; } return this.VALUE_UPDATED; }, ... } }();
用法示例:
var result = deepDiffMapper.map({ a: 'i am unchanged', b: 'i am deleted', ... }, { a: 'i am unchanged', c: 'i am created', ... }); console.log(result);
以上是如何在 JavaScript 中实现对象和数组的通用深度差异?的详细内容。更多信息请关注PHP中文网其他相关文章!