@bluelovers/deep-diff

中文文档
2.0.1发布于 2026/04/03MITTypeScriptESM + CJS零依赖近 30 天下载 4417

Javascript 用于计算深差,捕获变化,并在对象之间应用变化;用于节点和浏览器.

中文使用文档
文档目录11 节
  1. 安装
  2. 特征
  3. 安装
  4. 导入
  5. 简单示例
  6. 差额
  7. 变动
  8. API 文档
  9. diff
  10. observableDiff
  11. 捐款

深潜

深潜 是一个javascript/node.js模块,提供用于确定对象间结构差异的功能,并包括一些用于应用对象间差异的功能.

安装

npm install @bluelovers/deep-diff

可能 v1.0 相容性 :

  • 数组中的元素现在按倒序处理,它会修正一些纠缠错误,但可能会打破一些用户
    • 如果您的代码依赖于报告差异的顺序, 那么您的代码将会被打破 。 如果你认为一个对象图是一棵大树,那么 deep-diff 执行 对象图的前序倒转然而,当遇到一个阵列时,阵列从一端到一端进行处理,每个元素在再下降时按顺序递归处理.

特征

  • 获取两个对象之间的结构差异 .
  • 观察两个对象之间的结构差异.
  • 当结构差异代表变化时,应用从一个对象到另一个对象的改变.
  • 当结构差异代表变化时,有选择地将改变从一个对象应用到另一个对象.

安装

npm install @bluelovers/deep-diff

导入

节点

var diff = require('@bluelovers/deep-diff').diff
// or:
// const diff = require('deep-diff');
// const { diff } = require('deep-diff');
// or:
// const DeepDiff = require('deep-diff');
// const { DeepDiff } = require('deep-diff');
// es6+:
// import diff from 'deep-diff';
// import { diff } from 'deep-diff';
// es6+:
// import DeepDiff from 'deep-diff';
// import { DeepDiff } from 'deep-diff';

浏览器

<script src="https://cdn.jsdelivr.net/npm/deep-diff@1/dist/deep-diff.min.js"></script>

在浏览器中, deep-diff 定义全局变量 DeepDiff。如果全局命名空间存在冲突,您可以恢复冲突的定义并指定 deep-diff 变成这样的变量 : var deep = DeepDiff.noConflict();。 。 。 .

简单示例

为了描述差异,变化围绕着 origin 对象。 为保持一致 origin 对象总是在 left-hand-side 行动。 这个 comparand,它可能包含变化,总是在 right-hand-side 行动.

var diff = require('@bluelovers/deep-diff').diff;

var lhs = {
  name: 'my object',
  description: 'it\'s an object!',
  details: {
    it: 'has',
    an: 'array',
    with: ['a', 'few', 'elements']
  }
};

var rhs = {
  name: 'updated object',
  description: 'it\'s an object!',
  details: {
    it: 'has',
    an: 'array',
    with: ['a', 'few', 'more', 'elements', { than: 'before' }]
  }
};

var differences = diff(lhs, rhs);

五.0.2.0及以上 (单位:千美元) 上面的代码片段将导致描述这些差异的下列结构:

[ { kind: 'E',
    path: [ 'name' ],
    lhs: 'my object',
    rhs: 'updated object' },
  { kind: 'E',
    path: [ 'details', 'with', 2 ],
    lhs: 'elements',
    rhs: 'more' },
  { kind: 'A',
    path: [ 'details', 'with' ],
    index: 3,
    item: { kind: 'N', rhs: 'elements' } },
  { kind: 'A',
    path: [ 'details', 'with' ],
    index: 4,
    item: { kind: 'N', rhs: { than: 'before' } } } ]

差额

差异作为一项或多项变动记录列报。 更改记录的结构如下:

  • kind - 说明变化类型;将是下列变化之一:
    • N - 表示新增加的财产/要素
    • D - 表明财产/要素被删除
    • E - 表明已编辑财产/内容
    • A - 表示数组内发生的变化
  • path - 属性路径(从左手边根)
  • lhs - 比较左手边的值( 未定义是否为“ N” 类型)
  • rhs - 比较右侧的值( 未定义是否为 “% ” )
  • index - 当类型 “% 1” 时, 表示变化发生的数组索引
  • item - 当类型“ A” 时, 包含一个嵌入式更改记录, 显示阵列索引上发生的更改

生成所有结构差异的更改记录 origin 财务报告和审定财务报表 comparand。这些方法只考虑对象本身的属性和数组元素;不考虑从对象原型链所继承的元素.

对数组的更改是简单记录的。 我们最关心的是结构的形状;因此我们不花时间来确定一个物体是否从数组中的一个插槽移动到另一个插槽. 相反,我们只记录结构 差别。 如果结构差异是从 comparand 页:1 origin 然后两个对象将比较为“ 深等” , 使用大多数 isEqual 执行,例如载于 摇篮 或者说 下划线。 。 。 .

变动

当两个对象不同时,可以观察到它们被计算时的区别,并有选择地将这些变化应用到原对象(左手侧)上.

var observableDiff = require('deep-diff').observableDiff;
var applyChange = require('deep-diff').applyChange;

var lhs = {
  name: 'my object',
  description: 'it\'s an object!',
  details: {
    it: 'has',
    an: 'array',
    with: ['a', 'few', 'elements']
  }
};

var rhs = {
  name: 'updated object',
  description: 'it\'s an object!',
  details: {
    it: 'has',
    an: 'array',
    with: ['a', 'few', 'more', 'elements', { than: 'before' }]
  }
};

observableDiff(lhs, rhs, function (d) {
  // Apply all changes except to the name property...
  if (d.path[d.path.length - 1] !== 'name') {
    applyChange(lhs, rhs, d);
  }
});

API 文档

标准导入 var diff = require('deep-diff') 在所有代码示例中假设。 导入结果为对象具有下列公共属性:

  • diff(lhs, rhs[, options, acc]) ——计算两个对象之间的差异,可选择使用指定的累积器.
  • observableDiff(lhs, rhs, observer[, options]) ——计算两个对象之间的相差,每个对象向一个观察函数报告.
  • applyDiff(target, source, filter) ——将源对象的任何结构差异应用到目标对象上,可选择过滤出每个差异.
  • applyChange(target, source, change) ——对目标对象应用单一更改记录. 注: source 未使用,可删除.
  • revertChange(target, source, change) 将单个更改记录还原为目标对象。 注: source 未使用,可删除.

diff

这个 diff 函数计算两个对象之间的相差.

参数

  • lhs - 左手操作;源对象.
  • rhs - 右手操作;正在从结构上将对象与原对象作比较.
  • options - 可具有下列属性的配置对象:
    • prefilter: 函数,用于决定差异分析是否应在对象图下继续。 此功能还可以取代 options 后向兼容性参数中的对象.
    • normalize: 预处理的函数 叶子 在树上.
  • acc - 可选累积器/阵列(要求它具有下列特性: push 函数)。 每种差异被推到指定的累积器上.

返回一系列变化,或者,如果没有变化, undefined。这原本是选中的,所以结果将会通过一个真实测试:

var changes = diff(obja, objb);
if (changes) {
  // do something with the changes.
}

过滤前对象属性

这个 prefilter'签名应为: function(path, key) 它应该返回任何真实值 path- 说吧key 组合,应当过滤。 如果经过过滤,则差异分析不会在已识别的对象-财产路径上进行进一步分析.

const diff = require('@bluelovers/deep-diff').diff;
const assert = require('assert');

const data = {
  issue: 126,
  submittedBy: 'abuzarhamza',
  title: 'readme.md need some additional example prefilter',
  posts: [
    {
      date: '2018-04-16',
      text: `additional example for prefilter for deep-diff would be great.
      https://stackoverflow.com/questions/38364639/pre-filter-condition-deep-diff-node-js`
    }
  ]
};

const clone = JSON.parse(JSON.stringify(data));
clone.title = 'README.MD needs additional example illustrating how to prefilter';
clone.disposition = 'completed';

const two = diff(data, clone);
const none = diff(data, clone,
  (path, key) => path.length === 0 && ~['title', 'disposition'].indexOf(key)
);

assert.equal(two.length, 2, 'should reflect two differences');
assert.ok(typeof none === 'undefined', 'should reflect no differences');

使对象属性正常化

这个 normalize'签名应为: function(path, key, lhs, rhs) 如果未实现正常化,它应返回病态值,或 [lhs, rhs] 阵列来替换原始值。 如果路径在 prefilter 阶段.

const diff = require('@bluelovers/deep-diff').diff;
const assert = require('assert');

const data = {
  pull: 149,
  submittedBy: 'saveman71',
};

const clone = JSON.parse(JSON.stringify(data));
clone.issue = 42;

const two = diff(data, clone);
const none = diff(data, clone, {
  normalize: (path, key, lhs, rhs) => {
    if (lhs === 149) {
      lhs = 42;
    }
    if (rhs === 149) {
      rhs = 42;
    }
    return [lhs, rhs];
  }
});

assert.equal(two.length, 1, 'should reflect one difference');
assert.ok(typeof none === 'undefined', 'should reflect no difference');

observableDiff

这个 observableDiff 函数计算两个对象之间的差额,并将每个对象报告给一个观察员函数.

参数

  • lhs - 左手操作;源对象.
  • rhs - 右手操作;正在从结构上将对象与原对象作比较.
  • observer - 向观察员报告.
  • options - 可具有下列属性的配置对象:
    • prefilter: 函数,用于决定差异分析是否应在对象图下继续。 此功能还可以取代 options 后向兼容性参数中的对象.
    • normalize: 预处理的函数 叶子 在树上.

捐款

在作出贡献时,铭记着这是一个目标: deep-diff 没有包的依赖性。 这在未来可能有所改变,但目前没有依赖关系.

请在提交公关前进行单位测试: npm test。希望您的PR包含额外的单位测试,以说明您的改变/修改!

当你跑的时候 npm test, 将进行 linting 操作, 任何 linting 错误将失败测试... 这包括代码格式化 .

感谢所有那些贡献至今的人们!

版本与发布记录

@bluelovers/deep-diff 共发布 3 个版本,首次发布于 2021/06/08;过去 12 个月发布了 1 个版本。

版本发布日期距今
2.0.1latest2026/04/037 个月前
1.0.32022/08/064 年前
1.0.22021/06/085 年前

关于 @bluelovers/deep-diff 的常见问题

@bluelovers/deep-diff 是什么?

Javascript 用于计算深差,捕获变化,并在对象之间应用变化;用于节点和浏览器.

如何安装 @bluelovers/deep-diff?

在项目目录运行 npm install @bluelovers/deep-diff,或使用 pnpm add / yarn add / bun add。

@bluelovers/deep-diff 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@bluelovers/deep-diff 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@bluelovers/deep-diff 可以商用吗?

@bluelovers/deep-diff 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@bluelovers/deep-diff 的下载量有多少?

根据 npm 官方下载统计,@bluelovers/deep-diff 在 2026/10/09 – 2026/11/07 这 30 天内被下载 4,417 次,日均约 147 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@bluelovers/deep-diff 还在维护吗?

最新版本 2.0.1 发布于 2026/04/03(7 个月前);至今共发布 3 个版本,其中过去 12 个月发布了 1 个;首次发布于 2021/06/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。