首页 >web前端 >js教程 >如何在 JavaScript 中实现对象和数组的通用深度差异?

如何在 JavaScript 中实现对象和数组的通用深度差异?

Barbara Streisand
Barbara Streisand原创
2024-11-15 12:58:02500浏览

How to Implement a Generic Deep Diff for Objects and Arrays in JavaScript?

两个对象之间的通用深度比较

深度比较两个对象涉及识别它们之间的更改,包括添加、更新和删除。这可能很复杂,特别是对于嵌套对象和数组。

通用深度差异的现有库或代码

一种方法是实现一个通用的 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) &amp;&amp; this.isDate(value2) &amp;&amp; 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn