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

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

Barbara Streisand
发布: 2024-11-15 12:58:02
原创
491 人浏览过

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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板